0

私の最近の質問で、自分のequalsandhashcodeメソッドを(とりわけ)オーバーライドする必要があるとのことでした。そのため、少し時間をかけていくつかの記事を読み、適切な実装を考え出そうとしました。

ここに私が読んだ記事のいくつかがあります:

どの記事もなかなか良かったです。これを試みるのはこれが初めてなので、単純な (またはばかげた) 間違いを犯していないことを確認したいだけです。

オブジェクトが別のオブジェクトと同等nameかどうかを示すために使用します。この理由は、他のすべての変数は異なる可能性がありますが、名前は常に一意になるためです。PersonPerson

推奨される変更を反映するように更新

public class Person {

    private String name;
    private int p_number;
    private String address;
    //other variables

    public Person(String a_name) {
        name = a_name;
    }

    public String getName() {
        return name;
    }

    //other getters and setters

    @Override
    public boolean equals(Object o) {
        if(o == null) 
            return false;

        if(o == this) 
            return true;

        if(!(o instanceof Person)) 
            return false;

        Person p = (Person) o;
        return name.equals(p.name));

    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

私の質問は次のとおりです。

  1. これらのメソッドを正しく実装しましたか?
  2. 一意性を決定する唯一の変数であるためname、他の変数をわざわざチェックする必要がありますhashcodeか?
  3. 少し前に 31 が適切な素数として選択されたことを StackOverflow で読んでいましたが、今はより大きな素数を選択する方が良いですか? 誰かがこの主張を肯定または否定できますか? (主張は上記の3番目のリンクで行われました)

これらのメソッドを適切に実装していない場合、どうすれば変更/改善できますか?

4

2 に答える 2

3

equals()

if(name.equals(p.getName()))
    return true;

がありませんfalse。次のことができます。

// Both are Person instances, no need to use the accessor here
return name.equals(p.name);

に関してはhashCode()、ただreturn name.hashCode();

また、名前を null にすることはできますか? あなたの方法はそれを説明していないようです。(編集:答え:いいえ)

あなたの質問について:

名前は一意性を決定する唯一の変数であるため、ハッシュコード内の他の変数をわざわざチェックする必要がありますか?

いいえ、そうではありません。あなたの名前が同じで年齢が異なる場合、これは同じオブジェクトの異なるハッシュ コードにつながり、これはObject契約に違反します!

少し前に 31 が適切な素数として選択されたことを StackOverflow で読んでいましたが、今はより大きな素数を選択する方が良いですか? 誰かがこの主張を肯定または否定できますか? (主張は上記の3番目のリンクで行われました)

これは、わからない...

.equals()/コントラクトについてより完全にするために.hashCode()、Guava: のユーティリティ クラスについて言及しますEquivalence。特定のクラスに対するこの抽象クラスの実装により、これらのオブジェクトをメンバー (キー) として使用して、これらの関数の両方の異なる実装を持っているかSetのように を作成できます。Map

Equivalence<MyClass> eq = ....;

Set<Equivalence.Wrapper<MyClass>> set = ...;

set.add(eq.wrap(myClassInstance));

これは、実際にはいくつかのシナリオで非常に便利です...

于 2013-06-06T18:47:48.230 に答える