我正在完成学校作业,我需要存储一堆联系人。每个联系人都有HashSet
个社交网络帐户,地址和电话号码。
我不想在HashSet
中存储同一对象的多个副本,因此我已经为每个对象覆盖了hashCode()
和equals()
方法。
但是对于我的社交网络帐户对象,我的HashSet
会存储两次相同的对象!
我有两个不同的对象:
SocialNetworkAccount s1 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");
SocialNetworkAccount s2 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");
s1.equals(s2)
返回true
,s1.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;
}
答案 0 :(得分:2)
==运算符比较引用。由于有两个不同的对象,它们的引用会有所不同。
SocialNetworkAccount s1 = new SocialNetworkAccount(SocialNetworkAccount.AccountType.FACEBOOK, "wallcrawler123");
SocialNetworkAccount s2 = s1;
if (s1 == s2) {
System.out.println("The references are the same.");
}
答案 1 :(得分:2)
我怀疑问题是您的equals
方法不覆盖Object
's equals
method,其中Object
作为参数。
我怀疑您的equals
方法的参数为SocialNetworkAccount
,而不是Object
。我无法确切知道,因为您还没有发布equals
方法,但这是一个可能的解释。在这种情况下,equals
中的Object
方法不被覆盖,因此当HashSet
(最终)调用它时,它会调用Object
&# 39; s equals
方法,用于比较引用以查看它们是否相同。
如果是,请修改您的equals
方法以接受Object
而不是SocialNetworkAccount
,以便正确覆盖equals
。
此外,当一个打算覆盖另一个方法的方法实际上没有覆盖它时,使用@Override
注释将会捕获。
答案 2 :(得分: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替换为类中的值。
答案 3 :(得分: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]