1

次のコードは、コンパイルに合格することができます。instanceof Comparable である要素のみを受け取るように PriorityQueue を定義できるのはなぜですか?

...
PriorityQueue<Object> q = new PriorityQueue<Object>();
q.add(new Object());
...

ただし、予想される例外がスローされます。

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast     to java.lang.Comparable
    at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:595)
    at java.util.PriorityQueue.siftUp(PriorityQueue.java:591)
    at java.util.PriorityQueue.offer(PriorityQueue.java:291)
    at java.util.PriorityQueue.add(PriorityQueue.java:268)
    at ReentrantLockExample.main(ReentrantLockExample.java:12)
4

2 に答える 2

5

それはまたComparator、そうでない要素タイプのためにあなた自身を指定することを可能にするからですComparable。これは、、、および基本的に他のすべてのソートされたコレクションに も影響TreeSetします。TreeMap

独自のコードでそれを回避しようとしている場合は、コンストラクターよりもファクトリメソッドを優先してください。これは、さまざまなファクトリメソッドにさまざまな型制約を指定できるためです。たとえば、グアバ

<E extends Comparable> TreeSet<E> Sets.newTreeSet();
<E> TreeSet<E> Sets.newTreeSet(Comparator<? super E> comparator);
于 2012-05-17T15:21:31.777 に答える
1

を指定する限り、をComparable実装しないオブジェクトを保存できます。Comparator

ドキュメントから:

優先キューの要素は、使用されるコンストラクターに応じて、自然な順序に従って、またはComparatorキューの構築時に提供される順序に従って順序付けられます。null優先キューは要素を許可しません。自然順序付けに依存する優先キューも、比較できないオブジェクトの挿入を許可しません(そうすると、結果が生じる可能性がありますClassCastException)。

于 2012-05-17T15:21:29.293 に答える