4

Java の Set インターフェイスと SortedSet インターフェイスの間に論理的な矛盾があることに気付きました。

SortedSet は、(equal() メソッドによって) 異なるオブジェクトが比較中に同じである場合に等しいと認識しますが、これは論理的に正しくありません。オブジェクトの比較は、オブジェクトの順序のみを担当する必要があります。

例: たくさんの商品を持っていて、それらを価格で並べ替えたいとします。この場合、SortedSet には同じ価格の異なる製品を含めることはできません: [“salt”,0.5$], [“milk”, 1$], [“bread”, 1$], [“bananas”, 2$ ] 上記の例では、牛乳がパンに置き換えられます。この場合、等しくないオブジェクトが互いに置き換えられるため、継承された Set インターフェイスの規約に違反します。私は SortedSet の JavaDoc を赤字にして、この動作が十分に文書化されていることを知っていますが、これは論理的な失敗だと思います。

Set と SortedSet ですでに同様の問題を抱えているのではないでしょうか?

4

3 に答える 3

8

これは論理的な障害ではなく、設計上の特性です。比較アルゴリズムがequalsと一致している場合、はと同等にa.compareTo(b) == 0なることに注意してくださいa.equals(b)

javadocは、実際にはそれについて非常に明示的です。

ソートされたセットの動作は、その順序がequalsと矛盾している場合でも明確に定義されています。Setインターフェースの一般的な契約に従わないだけです。

それは役に立ちますか?

それは実際にあなたが特定の行動に到達したいところに柔軟性を与えます。たとえば、SortedSetに文字列を入れて、大文字と小文字を区別せずに並べ替える場合は、次を使用できます。

Set<String> set = new TreeSet<> (String.CASE_INSENSITIVE_ORDER);

それは期待される結果を達成しますが、これは:

set.add("ABC");
set.add("abc");

それらはその特定のコンパレータと等しいと見なされるため、セットに1つの文字列のみを追加します。

于 2013-01-26T07:10:47.273 に答える
0

おそらく、equals()で実際に使用できるメソッドを意味してObjectいるので、Javaのすべてのオブジェクトタイプはそれをオーバーライドするか、から継承しますObject

于 2013-01-26T07:08:53.020 に答える
0

Java では、一般的に言えば、2 つのオブジェクトabは同じですa.equals(b) == true。また、Set、すべての Set、さらには SortedSet に重複がないため、オーバーライドequalsして価格プロパティを比較すると、価格が同じであれば 2 つのオブジェクトは同じになります。

equalsメソッドをオーバーライドするのではなく、注文を行うためComparatorに toを提供すると思います。SortedSetこの場合、別の回答で述べたように、 ifa.compareTo(b) == 0は と同等になりa.equals(b)ます。

その Set を注文したい場合は、注文を行うための List のような別の構造が必要です。何かのようなもの:

List<Product> list = new ArrayList<Product>(myUnorderedProductsSet);
Collections.sort(list, comparatorByPrice);

これは Product Bean を複製したりコピーしたりするのではなく、同じオブジェクトへの参照を異なる順序で持つ別の構造になることに注意してください。高価でも避けられないものでもありません。

于 2013-01-26T07:25:41.850 に答える