如果我运行下面的代码,则输出为2,这意味着该集合包含2个元素。 但是我认为集应该含有1,因为基于哈希码()值以及两个对象相等.equals()
方法。 好像在我的理解一些明显的错误?
package HELLO;
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception {
Set<Alpha> s = new HashSet<Alpha>();
Alpha a1 = new Alpha();
Alpha a2 = new Alpha();
s.add(a1);
s.add(a2);
System.out.println(s.size());
}
}
class Alpha {
int a = 10;
public int hashcode() {
return a;
}
public boolean equals(Object obj) {
return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
}
public String toString() {
return "Alpha : " + a;
}
}
你的散列çODE方法不会覆盖Object类的哈希ÇODE方法,因此你的equals方法中断合同,因为它不符合的hashCode结果一致,你可以有是“平等”,但有不同的哈希码的对象。
记住:你应该总是使用@Override
标注覆盖方法,因为这将帮助您捕捉这一点,类似的错误。
@Override // ** don't forget this annotation
public int hashCode() { // *** note capitalization of the "C"
return a;
}
此外,你会想提高你的代码的格式,在这里为我们的评论投稿代码时尤其如此。 我们将能够更好地理解你的代码,并帮助你,如果它符合标准(这就是为什么标准已经存在)。 所以,尽量保持你的压痕与处于同一级别缩进相同的块中的所有行代码一致的,你会想,以确保基本级别的代码,包括进口,外部类的声明及其最终大括号,是左对齐:
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception {
Set<Alpha> s = new HashSet<Alpha>();
Alpha a1 = new Alpha();
Alpha a2 = new Alpha();
s.add(a1);
s.add(a2);
System.out.println(s.size());
}
}
class Alpha {
int a = 10;
@Override
public int hashCode() {
return a;
}
public String toString() {
return "Alpha : " + a;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Alpha other = (Alpha) obj;
if (a != other.a)
return false;
return true;
}
}
有关此美丽的,请阅读: 重写equals和hashCode在Java中
你的方法哈希码应该命名的hashCode(大写字母“C”)。
如果您计划覆盖方法,你应该使用@Override
注释。
如果您已经使用了注释,你已经注意到了这个问题前面的代码就不会编译。
该@Overrides注释是在超类”同名要覆盖的方法。
@Override
public int hashCode() {
return a;
}
@Override
public boolean equals(Object obj) {
return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
}
@Override
public String toString() {
return "Alpha : " + a;
}