19

TreeSet に 2 つの「従業員」オブジェクトを追加しようとしています。

Set<Employee> s = new TreeSet<Employee>();
s.add(new Employee(1001));
s.add(new Employee(1002));

しかし、それは ClassCastException をスローします:

Exception in thread "main" java.lang.ClassCastException: Employee cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(TreeMap.java:542)
    at java.util.TreeSet.add(TreeSet.java:238)
    at MyClient.main(MyClient.java:9)

ただし、TreeSet にオブジェクトを 1 つだけ追加すると、次のようになります。

Set<Employee> s = new TreeSet<Employee>();
s.add(new Employee(1001));

または、代わりに HashSet を使用する場合:

Set<Employee> s = new HashSet<Employee>();
s.add(new Employee(1001));
s.add(new Employee(1002));

そしたら成功です。例外が発生する理由と修正方法を教えてください。

4

6 に答える 6

26

Employeeを実装する必要があるかComparable、または を作成するときにコンパレータを提供するTreeSet必要があります。

これは、のドキュメントで詳しく説明されていますSortedSet

並べ替えられたセットに挿入されるすべての要素は、Comparableインターフェイスを実装する (または指定されたコンパレータによって受け入れられる) 必要があります。さらに、そのような要素はすべて相互に比較可能である必要があります: e1.compareTo(e2)(または)は、ソートされたセット内の要素に対してcomparator.compare(e1, e2)a をスローしてはなりません。この制限に違反しようとすると、問題のあるメソッドまたはコンストラクターの呼び出しで.ClassCastExceptione1e2ClassCastException

これらの要件を満たさない場合、ソート済みセットはその要素を比較する方法を認識できず、機能しません。

于 2013-04-11T07:33:06.850 に答える
2

TreeSetComparableカスタムが設定されていない場合は、要素にインターフェイスを実装する必要がありますComparator。代わりに/コントラクトをHashSet使用します。equalshashCode

他の要素と比較する必要がないため、 がTreeSet実装されていない要素を 1 つだけ追加できます。Comparable

ソース コードを見てみると、TreeMap.put(K key, V value)すべての質問の背後にある理由が明確にわかります (TreeSetは に基づいているTreeMapため、ソース参照です)。

于 2013-04-11T07:34:17.437 に答える
1

TreeSet#add(E) JavaDocから:

例外: ClassCastException - 指定されたオブジェクトを現在このセットにある要素と比較できない場合

基本的に必要なのは、オブジェクトに をEmployee実装Comparableまたは提供することです。ComparatorTreeSet

コードを確認TreeMapすると、コンパレータがオブジェクト内に見つからない場合、キー (オブジェクト) を直接にMapキャストしようとすることがわかります。EmployeeComparator

...
Comparable<? super K> k = (Comparable<? super K>) key;
...
于 2013-04-11T07:35:46.493 に答える
0

したがって、TreeSet は要素を並べ替えたままにしておく必要があるため、TreeSet を使用しているときに、必要に応じて Employee オブジェクトに Comparable インターフェイスを実装します。

于 2013-04-11T07:33:03.430 に答える
0

TreeSetの実装ですSortedSetEmployeeインターフェースを実装させるかComparable、適切なものを提供することができComparatorますTreeSet:

Set<Employee> s = new TreeSet<Employee>(new EmployeeComparator());
于 2013-04-11T07:35:06.867 に答える