3

equals() と hashcode() について読んでいるうちに、2 つのオブジェクトが等しい場合、それらのハッシュコードは等しいはずですが、その逆ではないことがわかりました。

しかし、以下の例はこれを反映していません。

class Employee{

  private String name;

  Employee(String name){
    this.name = name;
  }

  @Override
  public boolean equals(Object obj) {           
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

ここで、2 つの Employee オブジェクトを次のように作成するとします。

Employee e1 = new Employee("hi");
Employee e2 = new Employee("hi");

もしそうなら、印刷から明らかなハッシュコードが異なっていても、それはtruee1.equals(e2)を返します.e1.hashcode()e2.hashcode()

誰かが私を説明できますか?

4

4 に答える 4

10

hashcodeメソッドをオーバーライドし、equals と契約している実装を提供する必要があります。

   @Override
    public int hashCode() {
        return name == null ? 0 : name.hashCode();
    }
  • クラスが をオーバーライドする場合は、オーバーライドequalsする必要がありますhashCode
  • それらが両方ともオーバーライドされ、equalshashCodeなければならない場合use the same set of fields
  • 2 つのオブジェクトがequalである場合、それらのhashCodeequalも同様でなければなりません
  • オブジェクトが の場合、 はimmutableキャッシングhashCodeの候補であり、lazy initialization

ここでハッシュコードの実装について読むことができます

メソッドのデフォルトの動作をオーバーライドしない場合、Objectクラスから使用されます。

合理的に実用的である限り、クラス Object によって定義された hashCode メソッドは、個別のオブジェクトに対して個別の整数を返します。(これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されますが、この実装手法は JavaTM プログラミング言語では必要ありません。)

ハッシュベース[HashMap,HashSet,Hashtable,LinkedHashSet,WeakHashMap]のコレクションはhashCode()、バケット内のオブジェクトを検索/保存するために使用され、次に を呼び出しますequals()

于 2012-10-13T18:11:42.930 に答える
3

これは、メソッドをオーバーライドするたびに、equalsメソッドもオーバーライドする必要があるためhashcodeです。

それ以外の場合、オブジェクトはコードに従って比較されますが、HashCode は Object クラスで定義済みのアルゴリズムに従って計算されます。

objects:-一般に、等しいかどうかを確認する際に考慮したすべてのパラメーターは、 for eachall those parametersを計算するために使用する必要があります。hashcodesobject

andメソッドの使用法について説明しているこの非常に優れた投稿を参照してください。equalshashcode

すでに上で説明したこの投稿からの行を引用するには: -

メソッドで使用したものと同じフィールドのセットを使用して計算hashcodeしますequals

上記のステートメントを理解するために、以下のデモを見てみましょう: -

public class Demo {
    private String str;
    private String name;

    public boolean equals(Object obj) {
        // Suppose you compare two objects based on length of their name variable

        // If name equals, object are equal
        if (obj instanceof Demo) {
            return this.name.equals(((Demo)obj).name);
        }
        return false;
    }

    // ****** Badly Overrided hashcode *******
    public int hashcode() {
        // But you calculate hashcode using both the fields

        // You should never use this kind of code in hashcodes. 
        // Use complex algorithm which gives you distinct result for 
        // objects that are not equal.
        return str.length + name.length;
    }
}

したがって、2 つのオブジェクトの が同じnameである場合、それらは等しくなりますが、strフィールドの が異なる場合でも、lengthそれらhashcodesは異なります。

そのため、常にsame fieldsinequalshashcode計算を使用する必要があります。

于 2012-10-13T18:11:40.823 に答える
0

ハッシュコードメソッドをオーバーライドする必要があります。クラスがequalsをオーバーライドする場合、両方がオーバーライドされるときにhashCodeをオーバーライドする必要があり、equalsとhashCodeは、2つのオブジェクトが等しい場合は同じフィールドのセットを使用する必要があり、オブジェクトが不変の場合は、hashCode値も等しくなければなりません。キャッシングとレイジー初期化の候補

于 2012-10-13T19:06:13.407 に答える
0

hashCode期待どおりの動作を得るには、オーバーライドも必要です。ドキュメントObject.hashCodeによると、これは必須ではありませんが、デフォルトの実装はおそらくオブジェクト参照を返しています。

オーバーライドhashCodeしないと、特殊な結果は期待できません。これはオーバーライドに似ていますequals

于 2012-10-13T18:12:10.197 に答える