绊倒我发现这个非常有趣的程序,允许添加重复元素HashSet
.我希望有人可以很好地解释它
public class Human implements Comparable<Human> {
Integer age;
public Human(int age) {
this.age = age;
}
public int compareTo(Human h) {
return h.age.compareTo(this.age);
}
public String toString() {
return ""+this.age;
}
}
Run Code Online (Sandbox Code Playgroud)
主要课程
public class Test {
public static void main(String[] args) {
Set<Human> humans = new HashSet<Human>();
humans.add(new Human(13));
humans.add(new Human(33));
humans.add(new Human(21));
humans.add(new Human(21));
System.out.println("Size : "+humans.size());
System.out.print(humans);
}
}
Run Code Online (Sandbox Code Playgroud)
预期产出: [21, 33, 13]
取而代之的是: [21, 21, 33, 13]
你的类没有实现#hashCode
也没有#equals
- 失败了HashMap的实现契约(和HashSet,因为它在内部由HashMap支持).
http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
由于你的元素使用Object.hashCode()
/ equals()
,因此不考虑对象字段的值,唯一真正重要的是对象的内存地址[因为它是唯一区分没有显式hashCode()
/ equals()
]的对象的东西.
在使用基于散列的解决方案时定义比较器没有帮助 - 它仅适用于已排序的集合.
作为旁注:在您的代码中,这实际上是好的 - 您是否期望两个年龄相同的人是一个人?在这种情况下使用HashXXX的原因对我来说还不清楚 - 在这种特殊情况下,它没有比例如ArrayList更有益......
编辑:如果你完全确定你想要那种奇怪的行为 - 只需提供
public int hashCode() {
return age;
}
public boolean equals( Object obj ) {
if (this == obj)
return true;
if ( !(obj instanceof Human) ) // null check included for free ^_~
return false;
return age == ((Human)obj).age;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
122 次 |
最近记录: |