1

我正在做一项学校作业,我需要存储一堆联系人。每个联系人都有一个HashSet社交网络帐户、地址和电话号码。

我不想在 my 中存储同一个对象的多个副本HashSet,所以我已经覆盖了每个对象的hashCode()andequals()方法。

但仅对于我的社交网络帐户对象,我HashSet将同一个对象存储两次!我有两个不同的对象:

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方法没有覆盖Object's equalsmethod,它以 aObject作为参数。

我怀疑你的equals方法需要一个参数SocialNetworkAccount,而不是Object。我不能确定,因为你还没有发布你的equals方法,但这是一个可能的解释。在这种情况下,equals方法 inObject没有覆盖,因此当HashSet(最终)调用它时,它会调用Objectequals方法,该方法比较引用以查看它们是否相同。

如果是这样,请修改您的equals方法以接受 aObject而不是 a SocialNetworkAccount,以便equals正确覆盖。

此外,@Override当一个打算覆盖另一个方法的方法实际上没有覆盖它时,使用注释将捕获它。

于 2013-11-01T23:35:44.573 回答
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(...) 方法必须返回 true 才能将两个实例视为相同。

由于您没有向我们展示 equals 方法,我假设您没有创建自己的版本,这意味着 HashTable 正在使用默认实现,a == b并且您的两个实例不是同一个实例,因此返回 false,因此有两个条目在表中。

您还需要实现 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 回答