これは(太字の私の)JavaDocでTreeSet
かなりよく文書化されているようです:
インターフェースを正しく実装するためには、セットによって維持される順序(明示的なコンパレーターが提供されているかどうかに関係なく)がequalsと一致している必要があることに注意してください。Set
( equalsとの整合性の正確な定義については、Comparable
またはComparator
を参照してください。)これは、Set
インターフェイスがequals
操作の観点から定義されているためですが、TreeSet
インスタンスはそのcompareTo
(またはcompare)メソッドを使用してすべての要素の比較を実行するため、この方法は、セットの観点からは同じです。セットの動作は、その順序がequalsと矛盾している場合でも明確に定義されています。Set
インターフェイスの一般的な契約に従わないだけです。
これは、実装しているが一貫性がない唯一の(?)JDKクラスの例です。Comparable
equals()
Set<BigDecimal> decimals = new HashSet<BigDecimal>();
decimals.add(new BigDecimal("42"));
decimals.add(new BigDecimal("42.0"));
decimals.add(new BigDecimal("42.00"));
System.out.println(decimals);
decimals
、、は関係する限り等しくないため42
、最後に3つの値が42.0
あります。ただし、に置き換えると、結果のセットには1つのアイテム(たまたま最初に追加されたアイテム)のみが含まれます。これは、を使用して比較すると、すべてのアイテムが等しいと見なされるためです。42.00
equals()
HashSet
TreeSet
42
BigDecimal.compareTo()
これは、と一致しない型を使用TreeSet
すると、ある意味で「壊れequals()
ている」ことを示しています。それでも正しく機能し、すべての操作が明確に定義されています-クラスのコントラクトに従わないだけです-2Set
つのクラスがそうでない場合equal()
、それらは重複とは見なされません。
も参照してください