Java hashmap对象引用如何更改

Java hashmap对象引用如何更改,java,hashmap,Java,Hashmap,正在尝试检查hashmap的工作方式 public class hashmapcheck { public static void main(String args[]) { Person abhishek = new Person("abhishek"); Map<Person,String> mapCheck = new HashMap<Person,String>(); mapCheck.put(abhishek,"ancd"); a

正在尝试检查hashmap的工作方式

public class hashmapcheck {
public static void main(String args[]) {
    Person abhishek = new Person("abhishek");
    Map<Person,String> mapCheck = new HashMap<Person,String>();
    mapCheck.put(abhishek,"ancd");
    abhishek.setName("defg");
    System.out.println(mapCheck.get(abhishek));  //line which i try to undertand
}
}

若并没有为person类重写equals和hashcode,它将打印ancd,但当我重写它时,它将打印null。 当我在hashmap中存储object时,我想它会存储该hashmap的引用出错的地方。setName(“defg”)是在您将其添加到
hashmap
后,对您的
hashmap
(一个
Person
实例)的一个键进行变异

这会导致该键的
hashCode()
发生更改,因此
get()
方法无法根据新的
hashCode()
找到它(因为它被放置在与原始
hashCode()
匹配的容器中)

您误用了
HashMap
类。键在添加到
HashMap
后不应进行变异(至少不应变异影响
hashCode
equals
结果的属性)


至于不重写
equals
hashCode
时的行为,在这种情况下
equals
asd
hashCode
不依赖于
name
的值,因此更改
name
没有任何区别。在这种情况下,默认实现保证可以在
中找到您的密钥hMap
如果您正在搜索与您放入
映射中的
Person
实例完全相同的
实例,那么为什么直到我在Person对象中重写hashcode函数时它才更改呢。要补充回答:从映射接口的文档中:注意:如果可变对象用作映射键,必须非常小心。当对象是映射中的键时,如果对象的值以影响相等比较的方式更改,则不会指定映射的行为。@abhishekvashistha我添加了一个解释。感谢Eran,这是一个很大的帮助,已经在java上工作了一段时间,但缺少一些概念,只是尝试尽可能多地玩。还有一件事hashmap有自己的hashcode函数来获取对象的hashcode,那么为什么它在第一种情况下没有失败。不清楚您在问什么问题。您期望或试图实现什么?只是尝试研究hashmap和对象hashcode的行为
public class Person {
public String getName() {
    return name;
}

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

public Person(String name) {
    this.name = name;
}

String name;

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Person person = (Person) o;

    return name != null ? name.equals(person.name) : person.name == null;
}

@Override
public int hashCode() {
    return name != null ? name.hashCode() : 0;
}