web-dev-qa-db-ja.com

Javaカスタム等値基準のハッシュセット?

Java TreeSetがインスタンス化時にカスタムコンパレータを受け取る機能に似たものを探していたので、オブジェクトのデフォルトの等式(およびハッシュコード)基準を使用する必要はありませんでした。

私が思いついた最も近い方法は、オブジェクトをプライベートカスタムクラスでラップすることでしたが、それはハックのようです:(これは、プログラミングの際に一種の繰り返しのテーマになるので、使用可能なものがあるかどうか疑問に思っていました。たぶん、コモンズライブラリに?

ありがとう

36

いいえ、使用するはずのソリューションを正確に見つけました。

TreeSetであっても、equalsと互換性のない比較基準を使用するのは frowned on です。

並べ替えられたセットがSetインターフェイスを正しく実装する場合、並べ替えられたセット(明示的なコンパレータが提供されているかどうかに関係なく)によって維持される順序は、等しいと一致する必要があることに注意してください。

(Apache Commonsについては知りませんが、グアバ 具体的に拒否 この種の要求。)

15
Louis Wasserman

カスタム等価ロジックを許可するサードパーティのコレクションフレームワークがいくつかあります。これは、ソースを変更できないオブジェクトの同等性をオーバーライドするのに最適です。

Troveのマップ/セットは、カスタムハッシュ戦略の使用をサポートしており、入力データの特性に基づいてコレクションを調整できます。この機能を使用すると、Object.hashCode()をオーバーライドできない場合にハッシュ関数を定義することもできます。

これを実現するには、標準の修正が必要な型は、HE-CollectionインターフェイスEqualsAndHashCorrectionを実装する必要があります。このインターフェースは、メソッドhashCodeInHeCollection()およびequalsInHeCollection(Object)を定義します。これらのメソッドは、実装された誤ったメソッドhashCode()およびequals(Object)の修正として機能します。

3
Steve Kuo

TreesTreeMapTreeSet)のいずれかを使用する場合、追加するオブジェクトはComparableを実装する必要があります。

プリミティブ型の場合、Javaがこれを解決しました。
カスタムオブジェクトには、3つの可能性があります。

  1. オブジェクトの1つには、プリミティブ型の一意のIDまたはcompareTo()Stringなど)を既に実装しているTypeの一意のIDが既にあります。次に、他の値が平等のために重要です。 (ただし、equals()もこの1つのフィールドのみを使用する必要があります)

  2. ApacheのEqualsBuilderを使用:これはリフレクションで機能し、最速のソリューションではありません

  3. それを自分で書いて、それを行う方法のチュートリアルを読んでください:例:

Josh Bloch:Effective Java 2nd Edition

ただし、equals()compareTo()は互換性がなければならず(また、hashCode()も)、equalsコントラクトに違反しないようにする必要があることを忘れないでください。 (契約自体はあまり理解できませんが、そのいずれかをチュートリアルと同等にすることで明確になります。)

または、そのすべてを忘れて、HashSetHashMapを使用します。

3
AlexWien