4

どうして私はこれをすることが許されているのですか?

TreeSet<Object> treeSet = new TreeSet<Object>();
treeSet.add(new Object());

しかし、これではありません:

final List<Object> objects = new ArrayList<Object>();
Collections.sort(objects);

最初のものは私にClassCastExceptionを与えますが、2番目のものは私にコンパイルエラーを与えます。私が理解しているように、実際の問題はどちらの場合も同じです。Comparableインターフェースjava.lang.Objectを実装していません。

更新:うーん、何らかの理由で、これはJava 7にのみ適用され、6には適用されません。私は愚かで疲れていますか?誰かがこれに光を当ててくれませんか?

更新#2:Javaのバージョンに応じて異なる結果が得られます。写真をご覧ください: ここに画像の説明を入力してください

4

4 に答える 4

5

最初はここで眉をひそめましたが、その通りです。

SortedSetインターフェイスでは、ジェネリック型を指定する必要はありません。また、ではない型のを指定することComparableTreeSetできます。コンパイラーは2つのオプションを区別できません。ComparatorComparable

于 2013-01-25T14:33:18.637 に答える
4

Collections.sort'のリストが必要Comparableです。 TreeSetタイピングにその制限はありません。デフォルトのコンストラクターでは、ドキュメントは「要素の自然順序付け」でソートすると述べています。明確ではないのは、それがどのようにソートされるかですObjectが、あなたの問題はタイピングに関係しています。

更新:質問の最後の部分を見逃しました。TreeSetスタックトレースを見ずに、のデフォルトコンストラクターは「自然順序」で並べ替えようとするため、内部的には、へのキャストを実行していると推測されます。Comparableこれにより、が発生しClassCastExceptionます。

TreeSet更新: (JDK 6JDK 7)のjavadocsを詳しく調べたところ、

要素の自然順序に従ってソートされた、新しい空のツリーセットを構築します。セットに挿入されるすべての要素は、Comparableインターフェースを実装する必要があります。さらに、そのような要素はすべて相互に比較可能である必要があります。e1.compareTo(e2)は、セット内の要素e1およびe2に対してClassCastExceptionをスローしてはなりません。ユーザーがこの制約に違反する要素をセットに追加しようとすると(たとえば、ユーザーが要素が整数であるセットに文字列要素を追加しようとすると)、add呼び出しはClassCastExceptionをスローします。

両方のための。したがって、JDK6でClassCastExceptionが発生しない場合は、おそらくバグです。

于 2013-01-25T14:33:39.377 に答える
4

を渡して構築できるためTreeSet<E>、実装するオブジェクトに制限されないためです。ComparableComparator<E>

Collections.sort(T)Tを実装する必要がありますComparable。任意のオブジェクトを受け入れる別のメソッドがありCollectionsますが、を指定する必要がありますComparator

結局のところ、オブジェクトが実装されているためにオブジェクトが自然な順序になっているのComparableか、それともオブジェクトに作業を行うために必要なものを与えているのかによって異なりますComparator

于 2013-01-25T14:33:59.703 に答える
2

コレクションのソート関数のシグネチャを参照してください。

public static <T extends Comparable<? super T>> void sort(List<T> list)

Comparableインターフェイスを実装するオブジェクトを期待しています。そのため、コードにコンパイル時エラーが表示されます。

ただし、Treesetの場合、追加された要素がComparableを実装する必要があるという制限はありません。これは、適切に機能するためにのみ必要です。

于 2013-01-25T14:36:40.313 に答える