同じハッシュを持つオブジェクトと同じでなければなりませんか?

TMOTTM:

この下の例では、私はまったく同じ内部構造を持つ2つのオブジェクトを作成します。キャリーは何もありませんが、インスタンス変数として値1の両方。私の考えは、私が取る場合のハッシュということですe1、それはのハッシュと同じでなければなりませんe2ので、e1.equals(e2)trueを返す必要があります。

class EqualsChecker {

    public static void main(String[] args) {

        Elem e1 = new Elem(1);
        Elem e2 = new Elem(1);


        System.out.println(e1);                                // EqualsChecker$Elem@6ff3c5b5
        System.out.println(e2);                                // EqualsChecker$Elem@3764951d
        System.out.println("e1.equals(e2): " + e1.equals(e2)); // returns false
    }


    static class Elem {
        private int v;
        public Elem(int i) {
            this.v = i;
        }   
    }   
}

なぜequalsここに戻りfalseが?私は以下のスケッチでミドルケースを持っていると思います:ここでは、画像の説明を入力します。

アービンド・クマールのAvinash:

次の点を見てくださいhttps://docs.oracle.com/javase/9​​/docs/api/java/lang/Object.html#hashCode--

  1. オブジェクトが変更された上で、それは、Javaアプリケーションの実行中に複数回同じオブジェクトで呼び出されるたびに、hashCodeメソッドは一貫して同じ整数を返す必要があり、等号の比較に使用される情報を全く設けられていません。この整数は同じアプリケーションの別の実行へのアプリケーションの1つの実行の一貫性を維持する必要はありません。
  2. 2つのオブジェクトが等しい(オブジェクト)の方法に従って等しい場合には、同じ整数の結果を生成しなければならない二つの物体の各々にhashCodeメソッドを呼び出します。
  3. 2つのオブジェクトが等しい(java.lang.Objectの)方法に従って等しくない場合には、別個の整数結果を生成しなければならない二つの物体の各々にhashCodeメソッドを呼び出すことが必要とされません。しかし、プログラマは、等しくないオブジェクトについては異なる整数値が生成するハッシュテーブルの性能を向上させることができることに注意すべきです。
  4. 合理的に実用的である限り、クラスオブジェクトによって定義されたhashCodeメソッドは、異なるオブジェクトの異なる整数値を返しません。(ハッシュコードは、またはある時点で、オブジェクトのメモリアドレスの一部の機能として実現してもしなくてもよいです。)

さて、次のコードと、その出力を見てみましょう。

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

出力:

true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
false
employee2.hashCode(): 1297685781

以来employee3と同じオブジェクトを指しているemployee1間、あなたは彼らのために同じハッシュコードを取得している、employee2別のオブジェクトを指している(それは同じ内容を有しているが、キーワードは、newメモリ内の別のオブジェクトを作成します)そのため、あなたはまれかもしれません以下のために同じハッシュコードを取得するemployee2ポイント#4ドキュメントの状態から、上述しました:As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.

あなたはオーバーライドする必要がありますhashCode2つのオブジェクトが同じ内容などを持つために、同じハッシュコードを返す必要がありますように、方法を

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }   
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

出力:

true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
false
employee2.hashCode(): 128107556

実装hashCode上記のに対して同じハッシュコードを生成employee1し、employee2にもかかわらずequals戻るfalse(としてのチェックポイント#3ドキュメントから上記)。

オーバーライドの間違った方法は、hashCode例えば、異なるハッシュコードを返しても、同じオブジェクトを生じ得ます

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : (int) (code.length() * (Math.random() * 100)));
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee1.hashCode() again: " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

出力:

true
employee1.hashCode(): 66066760
employee1.hashCode() again: 66069457
employee3.hashCode(): 66073797
false
employee2.hashCode(): 66074882

これは、オーバーライドの間違った方法でhashCode起動するためhashCodeのJavaアプリケーションの実行中に複数回、同じオブジェクトには一貫して(ASチェック同じ整数を返さなければならない点#1ドキュメントから上記)。

さて、次のコードと、その出力を見てみましょう。

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

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

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

出力:

true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
true
employee2.hashCode(): 1297685781

のでemployee1.equals(employee2)戻りtrue、ハッシュコードも同じ(チェック返さなければならない点#2のドキュメントから上記)。しかしながら、ハッシュコードの値employee1employee2正確されていない異なります。我々が上書きされていないので、この違いはあるhashCode方法を。だから、あなたがオーバーライドする時はいつでもequals、あなたはまた、オーバーライドする必要がありますhashCode正しい方法をインチ

最後に、下記のを実装するための正しい方法であるhashCodeequals

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

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

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

出力:

true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
true
employee2.hashCode(): 128107556

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=282375&siteId=1