作者:王振cmcc | 来源:互联网 | 2022-10-22 10:32
我在弄乱试图理解HashSet的行为时遇到了麻烦,但遇到了一个我无法理解的问题。第二个和第三个狗对象具有相同的名称,equals()
并且hashcode()
已被覆盖以使名称表示相等。尽管如此,hashSet仍然有重复项,我不知道为什么。
我重新阅读了Head First Java的“数据结构”一章,但是它仍然建议我的代码在理论上应该可以工作。
public class DataStructsTests {
HashSet tree = new HashSet();
HashSet treeOwner = new HashSet();
public static void main(String[] args) {
DataStructsTests d = new DataStructsTests();
d.go();
}
public void go() {
Dogs dog = new Dogs("Scout", "a");
tree.add(dog);
treeOwner.add(dog);
Dogs dog2 = new Dogs("Brodie", "b");
tree.add(dog2);
treeOwner.add(dog2);
Dogs dog3 = new Dogs("Brodie", "c");
tree.add(dog3);
treeOwner.add(dog3);
System.out.println(tree);
System.out.println(treeOwner);
System.out.println(dog2.equals(dog3));
System.out.println(dog2.hashCode() + " " + dog3.hashCode());
}
class Dogs {
private String name;
private String ownerName;
public Dogs(String n, String o) {
name = n;
ownerName = o;
}
public boolean equals(Dogs d) {
return name.equals(d.getName());
}
public int hashCode() {
return name.hashCode();
}
public String getName() {
return name;
}
public String toString() {
return name;
}
运行程序将返回以下内容:
[Brodie, Brodie, Scout]
[Brodie, Brodie, Scout]
true
1998211617 1998211617
即使equals()
返回true并且哈希码相同,重复项仍然保留。
编辑:原来的问题是,当我使用Dog而不是Object时,我没有正确重写equals()方法。
1> Ben I...:
equals
采用类型的目的Object
,这是通过被称为一个HashSet
。您需要类似:
@Override
public boolean equals(Object d) {
if (! d instanceof Dogs){
return false;
}
return name.equals(((Dogs) d).getName());
}
以下是此答案的组成部分:
public boolean equals(Object d)
- equals
,至少是从继承的版本Object
定义为Object
,因此要覆盖它,还必须使用Object
。
@Override
-告诉编译器警告您,如果您像在问题中一样犯了错误。
d instanceof Dogs
-检查Object
馈入是否甚至是Dogs
第一个。
((Dogs) d).getName()
-之所以投来Dogs
是因为d
目前正在通过为Object
,这样你就不会自动获取Dogs
的方法,除非你明确地说,您要查看的Object
作为Dogs
。
最后一点:Java中的常规约定是使用单数形式命名类,除非出于某些原因相信每个实例将包含多个对象。这是为了避免歧义。 Dog d
明确什么d
是; 显然是一个Dog
。究竟是Dogs d
什么?有d
很多只狗,但是它们没有自己的对象类型?它变得有点模棱两可。