Java 理解Hashmap-put方法

Java 理解Hashmap-put方法,java,Java,我试图理解HashMap的put行为,我对下面的场景有点困惑。下面是我将在HashMap中用作键的一个类的实现 class Person { int id; String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() {

我试图理解HashMap的put行为,我对下面的场景有点困惑。下面是我将在HashMap中用作键的一个类的实现

class Person {
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.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;
        Person other = (Person) obj;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}
出于测试目的,我有一个util方法

public  void displayMap() {
        Person person = new Person();
        person.setId(1);
        person.setName("praveen");
        Map<Person, String> mapPerson = new HashMap<>();
        mapPerson.put(person, "");
        person.setId(2);
        person.setName("praveen");
        mapPerson.put(person, "");
        System.out.println(mapPerson);
    }
public void displayMap(){
Person=新人();
人.setId(1);
person.setName(“praveen”);
Map-mapPerson=新建HashMap();
mapPerson.put(person,“”);
人.setId(2);
person.setName(“praveen”);
mapPerson.put(person,“”);
系统输出打印LN(mapPerson);
}
我希望输出是
{Person[id=1,name=praveen]=,Person[id=2,name=praveen]=}
,但我认为它是
{Person[id=2,name=praveen]=,Person[id=2,name=praveen]=}

我使用同一个人对象作为键插入多次,但id值不同。但据我所知,如果钥匙是相同的,最好用新钥匙替换现有钥匙。但我看到的是Id=2,name=praveen的人多次显示。这不是密钥的重复吗?这违反了使用重复密钥的hashmap的原则吗?为什么它会显示
{Person[id=2,name=praveen]=,Person[id=2,name=praveen]=}
而不是
{Person[id=1,name=praveen]=,Person[id=2,name=praveen]=}
来自地图Javadoc:

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

该指令的总结:永远不要修改你刚刚作为映射键输入的东西,坏事情会发生,并且没有办法知道会发生什么坏事情

你修改了作为地图键输入的东西,基本上发生了不好的事情

您应该为第二次插入启动一个新的
Person
对象,然后事情就会正常、正确地发生。

从Map Javadoc:

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

该指令的总结:永远不要修改你刚刚作为映射键输入的东西,坏事情会发生,并且没有办法知道会发生什么坏事情

你修改了作为地图键输入的东西,基本上发生了不好的事情


您应该为第二次插入启动一个新的
Person
对象,然后事情就会正常正确地发生。

出于好奇,您是否尝试过在mapPerson中比较这两个值?它们是等价的吗?我是这样做的,它返回的结果同样奇怪,你有没有试着在mapPerson中比较这两个值?它们是等价的吗?我是这样做的,它返回的是相等的。你的意思是说,在这种情况下,行为是不可预测的?我很好奇为什么second-put语句会更改id=1的键,因为您存储的是对该键的引用,而不是副本。在您的整个程序中,只有一个人对象。现在知道了。Thanksor,换句话说,相同的Person实例在地图中保存了两次(不同的槽)(id=1保存时保存一个槽,id=2保存时保存第二个槽)您的意思是说在这种情况下不会预测该行为?我很好奇为什么second-put语句会更改id=1的键,因为您存储的是对该键的引用,而不是副本。在您的整个程序中,只有一个人对象。现在知道了。Thanksor,换句话说,相同的Person实例在地图中保存了两次(不同的槽位)(id=1时保存一个槽位,id=2时保存第二个槽位)