当我们在Set中添加元素时,它将丢弃重复的值。当我们删除集合k1和k2的元素时。最终的大小是1.代码的答案是2:2:1:1。
class KeyMaster {
public int i;
public KeyMaster(int i) {
this.i = i;
}
public boolean equals(Object o) {
return i == ((KeyMaster) o).i;
}
public int hashCode() {
return i;
}
}
public class MapIt {
public static void main(String[] args) {
Set<KeyMaster> set = new HashSet<KeyMaster>();
KeyMaster k1 = new KeyMaster(1);
KeyMaster k2 = new KeyMaster(2);
set.add(k1);
set.add(k1);
set.add(k2);
set.add(k2);
System.out.print(set.size() + ":");
k2.i = 1;
System.out.print(set.size() + ":");
set.remove(k1);
System.out.print(set.size() + ":");
set.remove(k2);
System.out.print(set.size());
}
}
答案 0 :(得分:1)
这是因为HashSet中的键不是不可变的所以当您更改k2
的字段值时,此字段值已更改但对象保持不变,因此当您要删除时来自集合的k2
,它无法找到k2,因为您的对象已被更改。
为了更好地理解它,让k1
去测试一下:
class MapIt {
public static void main(String[] args) {
Set<KeyMaster> set = new HashSet<KeyMaster>();
KeyMaster k2 = new KeyMaster(2);
set.add(k2);
set.add(k2);
System.out.print(set.size() + ":");
k2.i = 3;
System.out.print(set.size() + ":");
set.remove(k2);
System.out.println(set.size());
}
}
答案 1 :(得分:1)
Map
(HashMap
的幕后HashSet
} API的界面说:
注意:如果将可变对象用作地图,则必须非常小心 键。如果对象的值,则不指定映射的行为 以一种影响等于比较的方式改变 对象是地图中的一个关键。
您的hashCode
定义不明确,至少应该确保以下内容(来自API):
每当在同一个对象上多次调用它时 执行Java应用程序时,hashCode方法必须始终如一 返回相同的整数,前提是equals中没有使用的信息 对象的比较被修改。不需要保留该整数 从一个应用程序的执行到另一个执行的一致性 相同的申请。