これは(太字の私の)JavaDocでTreeSetかなりよく文書化されているようです:
インターフェースを正しく実装するためには、セットによって維持される順序(明示的なコンパレーターが提供されているかどうかに関係なく)がequalsと一致している必要があることに注意してください。Set( equalsとの整合性の正確な定義については、ComparableまたはComparatorを参照してください。)これは、Setインターフェイスがequals操作の観点から定義されているためですが、TreeSetインスタンスはそのcompareTo(またはcompare)メソッドを使用してすべての要素の比較を実行するため、この方法は、セットの観点からは同じです。セットの動作は、その順序がequalsと矛盾している場合でも明確に定義されています。Setインターフェイスの一般的な契約に従わないだけです。
これは、実装しているが一貫性がない唯一の(?)JDKクラスの例です。Comparableequals()
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.00equals()HashSetTreeSet42BigDecimal.compareTo()
これは、と一致しない型を使用TreeSetすると、ある意味で「壊れequals()ている」ことを示しています。それでも正しく機能し、すべての操作が明確に定義されています-クラスのコントラクトに従わないだけです-2Setつのクラスがそうでない場合equal()、それらは重複とは見なされません。
も参照してください