1

たくさんの連絡先を保存する必要がある学校の課題をやっています。各連絡先には、HashSetソーシャル ネットワーク アカウント、住所、電話番号があります。

同じオブジェクトの複数のコピーを my に保存したくないので、各オブジェクトのandメソッドをHashSetオーバーライドしました。hashCode()equals()

しかし、私のソーシャル ネットワーク アカウント オブジェクトについてのみ、HashSet同じオブジェクトを 2 回保存しています。私は2つの異なるオブジェクトを持っています:

SocialNetworkAccount s1 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");

SocialNetworkAccount s2 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");

s1.equals(s2)戻っtrues1.hashCode() == s2.hashCode()戻ってきますtrueが、s1 == s2戻ってきますfalse!なんで?

これはhashCode()私が使用している方法です:

public int hashCode() {
    int prime = 31;
    int result = 1;
    result = result*prime + type.hashCode();
    result = result*prime + id.hashCode();
    return result;
}
4

4 に答える 4

2

問題は、あなたのequalsメソッドがmethodをオーバーライドしていないことだと思います。これは、をパラメーターとして受け取ります。ObjectequalsObject

あなたのメソッドはではなくequalsのパラメータを取ると思われます。メソッドを投稿していないため、確かなことはわかりませんが、考えられる説明です。この場合、 のメソッドはオーバーライドされないため、(最終的に) を呼び出すと、のメソッドが呼び出され、参照が同じかどうかが比較されます。SocialNetworkAccountObjectequalsequalsObjectHashSetObjectequals

その場合は、 a の代わりにequalsを受け入れるようにメソッドを変更して、適切にオーバーライドします。ObjectSocialNetworkAccountequals

また、@Overrideアノテーションを使用すると、別のメソッドをオーバーライドしようとするメソッドが実際にはオーバーライドしない場合にキャッチされます。

于 2013-11-01T23:35:44.573 に答える
2

== 演算子は参照を比較します。2 つの異なるオブジェクトがあるため、それらの参照は異なります。

SocialNetworkAccount s1 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");

SocialNetworkAccount s2 = s1;

if (s1 == s2) { 
    System.out.println("The references are the same."); 
}
于 2013-11-01T23:22:41.240 に答える
1

多分あなたはこのようなことをしましたか?

SocialNetworkAccount s1 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "foo");
SocialNetworkAccount s2 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "bar");

hashSet.add(s1);
hashSet.add(s2);

s2.setNickname("foo");

System.out.println(s1.equals(s2));  // true
System.out.println(hashSet);        // [FACEBOOK:foo, FACEBOOK:foo]
于 2013-11-02T00:23:01.973 に答える
1

hashCode メソッドはエントリをテーブルに大まかに割り当てるために使用されますが、 equals(...) メソッドは、2 つのインスタンスが同一として扱われるために true を返す必要があります。

equals メソッドを表示していないので、独自のバージョンを作成していないと仮定します。つまり、HashTable はデフォルトの実装を使用してa == bおり、2 つのインスタンスは同じインスタンスではないため、false が返されるため、2 つのエントリが返されます。テーブルで。

あなたがする必要があるのは、 equals メソッドも実装することです:

public boolean equals(Object o) {
    if (o == this) {
        return true;
    }
    if (o instanceof SocialNetworkAccount) {
        SocialNetworkAccount their = (SocialNetworkAccount)o;
        return xxx.equals(their.xxx ) &&  yyy.equals(their.yyy) && ...;
    }
    return false;
}

xxx や yyy などをクラスの値に置き換えます。

hashCode と equals コントラクトを参照してください

于 2013-11-01T23:23:50.230 に答える