equals
データ型で使用されるSet
メソッドをオーバーライドする方法はありますか? equals
というクラスのカスタムFee
メソッドを作成しました。現在、LnkedList
のFee
があり、重複したエントリがないことを確認したいと思います。したがって、Set
の代わりにLinkedList
を使用することを検討していますが、2つの料金が等しいかどうかを判断する基準は、equals
クラスのオーバーライドされたFee
メソッドにあります。
LinkedList
を使用する場合、すべてのリスト項目を反復処理し、パラメーターとして残りのエントリを使用して、equals
クラスのオーバーライドされたFee
メソッドを呼び出す必要があります。これだけを読むと、処理が多すぎるように聞こえ、計算が複雑になります。
Set
をオーバーライドされたequals
メソッドで使用できますか?したほうがいい?
ジェフ・フォスターが言ったように:
Set.equals()メソッドは、2つのセットが等しいかどうかを比較するためにのみ使用されます。
Set
を使用して重複エントリを取り除くことができますが、注意してください:HashSet
は、含まれているオブジェクトのequals()
メソッドを使用して同等性を判断しないでください。
HashSet
は、<Integer(HashCode), Object>
エントリを持つ内部HashMap
を持ち、equals()とHashCodeのequalsメソッドを使用して、等しいかどうかを判断します。
この問題を解決する1つの方法は、セットに入れたクラスのhashCode()
をオーバーライドして、equals()
基準を表すようにすることです。
例えば:
class Fee {
String name;
public boolean equals(Object o) {
return (o instanceof Fee) && ((Fee)o.getName()).equals(this.getName());
}
public int hashCode() {
return name.hashCode();
}
}
Setを使用して、オーバーライドされたequalsメソッドでオブジェクトタイプを保持できますが、hashCode()もオーバーライドする必要がある場合があります。等しいオブジェクトはハッシュコードが等しい。
例えば:
public Fee{
public String fi;
public String fo;
public int hashCode(){
return fi.hashCode() ^ fo.hashCode();
}
public boolean equals(Object obj){
return fi.equals(obj.fi) && fo.equals(obj.fo);
}
}
(もちろん、必要に応じてnullチェックを使用します。)
多くの場合、セットはhashCode()を使用してパフォーマンスを最適化し、hashCodeメソッドが破損していると誤動作します。たとえば、 HashSetは内部HashMapを使用します。
HashMapのソースコードを確認する場合 、要素のhashCode()メソッドとequals()メソッドの両方に依存していることがわかります。
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
ハッシュが正しく生成されない場合、equalsメソッドが呼び出されることはありません。
セットを高速化するには、可能な限り、等しくないオブジェクトに対して個別のハッシュコードを生成する必要があります。
Set
は、セットに追加されたオブジェクトのequalsメソッドを使用します。 JavaDoc 状態
重複する要素を含まないコレクション。より正式には、セットにはe1.equals(e2)などの要素e1とe2のペアは含まれず、最大1つのnull要素が含まれます。
Set.equals()
メソッドは、2つのセットが等しいかどうかを比較するためにのみ使用されます。セットへのアイテムの追加/削除の一部として使用されることはありません。
解決策の1つは、コンパレータで TreeSet を使用することです。
ドキュメントから:
TreeSetインスタンスは、compareTo(またはcompare)メソッドを使用してすべての要素比較を実行するため、このメソッドで等しいと見なされる2つの要素は、セットの観点からは等しいです。
このアプローチは、LinkedListを使用するよりもはるかに高速ですが、HashSetよりも少し遅くなります(ln(n)vs n)。
TreeSetを使用する1つの副作用として、セットがソートされることに注意してください。