2012-10-06 28 views
8

私はポスターを持っていた問題を正しく解決したコードhereを掲載しました。 OPは重複を取り除き、特定の特別なアイテムをリストの先頭に持ってきたかった。私はTreeSetを特別なComparableクラスを使用して、彼らが望んでいたものを達成するために働いていたLocaleを包みました。セットと同等と同等

私は、あなたがそうであるように...私はないequals実装からtrueを返すことによって、compareTo方法から0を返すことで、重複を排除したことが1が正しく重複を示すために行う必要があるだろうと...思考になりましたSetdefinition,Setから)。

私はこのテクニックを使用することに異論はありませんが、文書化されていない機能と考えられるものを使用していますか?このようなことを続けていくことが今後も続くと思いますか?

+0

も参照してください。私はそれが驚くべきことに同意する! –

答えて

17

それはかなりよくJavaDoc of TreeSet(太字鉱山)に記載されています。このように思える:順序はに等しいとは一致していなければならない(明示的なコンパレータが提供されているかどうか)のセットによって維持することを

注意Setインターフェイスが正しく実装されているかどうかを確認します。 (equalsと一貫性の正確な定義のためComparable又はComparatorを参照。)Setインタフェースがequals操作の観点で定義されているので、これはそうであるが、TreeSetインスタンスは、そのcompareTo(または比較)メソッドを使用して、すべての要素の比較を行い、したがって、この方法で等しいとみなされる2つの要素は、セットの観点からは等しい。 セットの動作は、順序がequalsと矛盾していても明確に定義されています。 Setインターフェイスの一般契約に従わないだけです。ここ

Comparableを実装しかしequals()と一致しないonly (?) JDK classの例である:最後に

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); 

decimals4242.0及び42.00は限りequals()として等しくないので、三つの値を有します心配している。しかし、HashSetTreeSetに置き換えた場合、結果セットには、BigDecimal.compareTo()を使用して比較した場合、すべてが等しいとみなされるため、1つのアイテム(42 - 最初に追加されたアイテム)のみが含まれます。

equals()と一致しないタイプを使用すると、TreeSetは「が壊れた」のようになります。それでも正常に動作し、すべての操作は明確に定義されています。Setクラスのコントラクトには従いません.2つのクラスがequal()でない場合、重複は考慮されません。

氏Nurkiewiczが指摘するように、これは指定された動作であるので、それが安全だ

+0

「ConcurrentSkipListSet」ドキュメントにそのようなコメントがないことに興味があります。 – OldCurmudgeon

+1

@OldCurmudgeon実際には[SortedSetのjavadoc](http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html)で指定されています(TreeSetとConcurrentSkipListSetの両方でインタフェース)。 – assylias

+0

それはそうです!良いキャッチ。 – OldCurmudgeon