我几天以来一直在使用HashMap,面对奇怪的情况。
案例1:已更改的密钥已存在于HashMap中,并打印HashMap 案例2:更改了HashMap中已存在的密钥并将该密钥再次放入HashMap。打印HashMap。
请查看以下代码以及两种情况的两种不同输出。
请问有谁让我知道,下面的代码是什么。
import java.util.HashMap;
import java.util.Set;
class Emp{
private String id ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Emp(String id) {
super();
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Emp other = (Emp) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return "Emp [id=" + id + "]";
}
}
public class HashMapChanges {
public static void main(String[] args) {
// TODO Auto-generated method stub
Emp e1 = new Emp("1");
Emp e2 = new Emp("2");
Emp e3 = new Emp("3");
Emp e4 = new Emp("4");
HashMap<Emp, String> hm = new HashMap<Emp,String>();
hm.put(e1,"One");
hm.put(e2,"Two");
hm.put(e3,"Three");
hm.put(e4,"Four");
e1.setId("5");
/** Uncomment below line to get different output**/
//hm.put(e1,"Five-5");
Set<Emp> setEmpValue = hm.keySet();
for(Emp e : setEmpValue){
System.out.println("Key"+ e +" Value "+ hm.get(e));
}
}
}
输出上述代码:
KeyEmp [id=2] Value Two
KeyEmp [id=5] Value null
KeyEmp [id=4] Value Four
KeyEmp [id=3] Value Three
取消注释行后的输出
KeyEmp [id=5] Value Five-5
KeyEmp [id=2] Value Two
KeyEmp [id=5] Value Five-5
KeyEmp [id=4] Value Four
KeyEmp [id=3] Value Three
答案 0 :(得分:4)
当用于确定其在Map中的位置的键是可变的时,不允许将可变对象用作Map中的键。
来自-lstdc++
的Javadoc:
注意:如果将可变对象用作映射键,则必须非常小心。如果在对象是地图中的键的情况下以影响等于比较的方式更改对象的值,则不指定映射的行为。
您违反了地图密钥所需的合同,因为您的java.util.Map<K,V>
对象是可变的,并且更改会修改用于确定密钥所在地图中的位置的属性。
结果是未定义的行为。
我怀疑你根据你的代码误解了Emp
概念,但是如果不了解你实际想要实现的目标,我们实在无法帮助你。我建议你提出一个新问题来解释你的实际目标。
答案 1 :(得分:-3)
您覆盖了hashCode()
和equals()
方法,
那么,Map的关键是hashCode结果。
然后id=1
和id=5
是两个不同的项目。
您可以对这两种方法发表评论,然后重试。