10

ポスターが抱えていた問題を正しく解決するコードをここに投稿しました。OPは、重複を削除し、特定の特別なアイテムをリストの一番上に表示したいと考えていました。私は彼らが望んでいたことを達成するために彼らが一緒に働いていたものを包んだTreeSet特別なクラスでを使用しました。ComparableLocale

それから私は...あなたがそうするように...私はメソッド0から戻ることによって重複を排除していると思いました。 (の定義から)で重複を正しく示すために必要な実装から戻ることではありません)。compareTotrueequalsSetSet

この手法を使用することに異論はありませんが、文書化されていない機能と見なされる可能性のあるものを使用していますか?このようなことを今後も続けていくと思いますか?

4

1 に答える 1

21

これは(太字の私の)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()、それらは重複とは見なされません。

も参照してください

于 2012-10-06T16:36:24.950 に答える