5
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ですか?

4

4 に答える 4

8

明示的なコンパレータなしでインスタンス化する場合TreeSet、挿入された要素がを実装することを期待しますComparableが、Classこのインターフェイスは実装しません。

修正するには、次のコンパレータを作成します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);
于 2010-08-17T11:45:58.787 に答える
3

TreeSetは順序集合であるため、挿入する要素はすべて実装する必要がありますComparable(カスタムを指定しない限りComparator)。 Classではない。

順序付けが必要ない場合は、 HashSetなどの順序付けされていないセットをいつでも使用できます。それ以外の場合は、独自の注文を考え出す必要があります。

Javadoc(強調鉱山)から:

TreeMapに基づくNavigableSetの実装。要素は、使用されるコンストラクターに応じて、自然順序付けを使用して、または設定された作成時に提供されるコンパレーターによって順序付けられます。

この実装は、基本操作(追加、削除、および含む)に保証されたlog(n)時間コストを提供します。

セットによって維持される順序(明示的なコンパレータが提供されているかどうかに関係なく)は、セットインターフェイスを正しく実装するためにequalsと一致している必要があることに注意してください。(equalsとの整合性の正確な定義については、ComparableまたはComparatorを参照してください。)これは、Setインターフェイスがequals操作で定義されているためですが、TreeSetインスタンスはcompareTo(またはcompare)メソッドを使用してすべての要素の比較を実行します。この方法で等しいと見なされる要素は、セットの観点からは等しいです。セットの動作は、その順序がequalsと矛盾している場合でも明確に定義されています。Setインターフェースの一般的な契約に従わないだけです。

参照:コンパレータ

于 2010-08-17T11:44:35.160 に答える
1

BlockquoteなぜこれがClassCastExceptionをスローするのですか?

これは、TreeMapの実装によって引き起こされました。TreeMapのキーセットであるTreeSetはそれに基づいています。

java.lang.Classはjava.lang.Comparableインターフェースを実装していないため、ClassCastExceptionの例外をスローします。

于 2010-08-17T12:34:27.697 に答える
0

実際のエラーはjava.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable です。これが-TreeSetは要素に順序を課します。HashSetを使用する場合は、すべて問題ありません。

于 2010-08-17T11:45:32.280 に答える