在Java中修改HashMap的现有键

在Java中修改HashMap的现有键,java,hashmap,Java,Hashmap,几天以来,我一直在使用HashMap,并面临以下奇怪的情况 案例1:更改了HashMap中已有的密钥,并打印HashMap 案例2:更改了HashMap中已经存在的密钥,并将该密钥再次放入HashMap中。打印HashMap 请查找下面的代码以及两个不同输出的两个案例 你能不能请任何人告诉我,在下面的代码中发生了什么 import java.util.HashMap; import java.util.Set; class Emp{ private String id ; pu

几天以来,我一直在使用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=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

当用于确定其在地图中的位置的键是可变的时,不允许将可变对象用作地图中的键

java.util.Map
的Javadoc中:

注意:如果将可变对象用作贴图键,则必须非常小心。如果对象是贴图中的关键点时,对象的值以影响相等比较的方式更改,则不会指定贴图的行为

您违反了映射键所需的约定,因为
Emp
对象是可变的,并且该更改修改了用于确定键在映射中的位置的属性

结果是未定义的行为


基于您的代码,我怀疑您误解了
Map
的概念,但如果不了解您实际想要实现的目标,我们真的无法进一步帮助您。我建议你问一个新问题来解释你的实际目标。

覆盖
hashCode()
equals()
方法, 然后,映射的键是hashCode结果。 那么
id=1
id=5
是两个不同的项目

您可以对这两种方法进行注释,然后重试

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