なぜtreeset.contains()が機能しないのですか?
-
29-09-2019 - |
質問
public class Empty {
public static void main( String[] args ) {
TreeSet<Class> classes = new TreeSet<Class>();
classes.add( String.class );
String test = new String();
try{
if( classes.contains(test.getClass()) ){
System.out.println( "contains" );
}
}catch(ClassCastException cce){
System.out.println( "Expected: " + classes );
System.out.println( "But it was: " + test.getClass() );
}
}
}
なぜこれが投げるのですか ClassCastException
?
解決
インスタンス化するとき TreeSet
明示的な比較器がなければ、挿入された要素が実装されることを期待しています Comparable
, 、 しかし Class
このインターフェイスを実装していません。
修正するには、Comparatorを作成します Class
:
Comparator<Class> classComp = new Comparator<Class>()
{
@Override
public int compare(Class o1, Class o2)
{
return o1.getName().compareTo(o2.getName());
}
};
TreeSet<Class> classes = new TreeSet<Class>(classComp);
他のヒント
TreeSet
注文されたセットなので、挿入する要素はすべて実装する必要があります Comparable
(カスタムを指定しない限り Comparator
). Class
ではない。
注文が必要ない場合は、いつでも順序付けられていないセットを使用できます。 ハッシュセット. 。それ以外の場合は、独自の注文を考え出す必要があります。
Javadoc(Emphasis Mine)から:
Treemapに基づくNavigablesetの実装。 要素は、自然な順序を使用して、またはセット作成時に提供されるコンパレータによって注文されます, 、どのコンストラクターが使用されるかによって異なります。
この実装は、基本操作の保証されたログ(n)時間コストを提供します(追加、削除、含める)。
ご了承ください セットによって維持される順序付け(明示的なコンパレータが提供されるかどうか)は、等しいものと一致する必要があります セットインターフェイスを正しく実装する場合。 (等しいと一致する正確な定義については、比較可能またはコンパレータを参照してください。)これは、SETインターフェイスが等しい動作に関して定義されているが、Treesetインスタンスはその比較(または比較)メソッドを使用してすべての要素比較を実行するためです。この方法で等しいとみなされる要素は、セットの観点から等しい。セットの動作は、その順序が平等と矛盾する場合でも、明確に定義されています。 SETインターフェイスの一般契約に従うことができません。
参照: コンパレータ
BlockQuoteなぜこれがClassCastExceptionを投げるのですか?
Treemapの実装によって原因であり、Treemapの重要なセットであるTreesetはそれに基づいています。
java.lang.classはjava.lang.comparableインターフェイスを実装していないため、ClassCastExceptionの例外がスローされます。
実際のエラーはです java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
. 。ここに - ツリーセットは要素に順序付けを課します。ハッシュセットを使用する場合、すべて問題ありません。