我有以下代码:
class Animal {
int i;
public Animal(){
i=13;
}
public String toString(){
return "Animal "+i;
}
}
//
public class NewMain {
public static void main(String[] args) {
HashSet hs=new HashSet();
boolean b=hs.add(new Animal());
boolean b1=hs.add(new Animal());
System.out.println(b+" "+b1);
for(Object o:hs)
{
System.out.println(hs);
}
}
}
我知道Set
不允许重复,但为什么上面的代码似乎允许两个相同的值?
答案 0 :(得分:7)
因为Java无法知道您的两个实例是相同的。
您需要覆盖equals()
和hashcode()
答案 1 :(得分:6)
正如已经指出的那样,您需要覆盖hashCode
和equals
。您可以在int i
上比较类似的内容,
class Animal {
int i;
public Animal() {
i = 13;
}
@Override
public String toString() {
return "Animal " + i;
}
@Override
public int hashCode() {
return Integer.hashCode(i);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Animal) {
return ((Animal) obj).i == i;
}
return false;
}
}
然后我建议您在Collection
使用泛型。此外,您应该在循环中打印实例(而不是Collection
)。像,
public static void main(String[] args) {
Set<Animal> hs = new HashSet<>();
boolean b = hs.add(new Animal());
boolean b1 = hs.add(new Animal());
System.out.println(b + " " + b1);
for (Animal a : hs) {
System.out.println(a);
}
}
我得到了(预期的)
true false
Animal 13
答案 2 :(得分:4)
您尚未在hashcode
课程中覆盖equals
和Animal
。因此,这些方法继承自java.lang.Object
。
继承的行为(来自Object
)是对象只有在相同的对象时才相等。
在这种情况下,equals
和hashcode
的一对合适的覆盖将是这样的:
@Override
public boolean equals(Object other) {
return other instanceof Animal &&
other != null &&
((Animal) other).i == this.i;
}
@Override
public int hashCode() {
return i;
}
(请注意,如果您开始创建Animal
的子类,则需要仔细考虑如何最好地实施equals(Object)
。通过以上代码,我们不会尝试处理... )