尝试检查哈希图如何工作
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
}
}
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;
}
}
如果等于,并且人员类的哈希码未覆盖,则打印acd,但是当我覆盖它时,它将打印null。 我在将对象存储在哈希图中时的想法,它将存储该哈希图的引用
答案 0 :(得分:8)
abhishek.setName("defg")
正在将您的HashMap
(一个Person
实例)的键添加到HashMap
后对其进行突变。
这会导致该键的hashCode()
发生更改,因此get()
方法无法根据新的hashCode()
来找到它(因为它被放置在与原始键匹配的垃圾箱中hashCode()
。
您正在滥用HashMap
类。将密钥添加到HashMap
后,不应对其进行突变(至少不应影响影响hashCode
和equals
的结果的属性)。
对于不覆盖equals
和hashCode
时的行为,在这种情况下equals
和hashCode
并不取决于name
的值,因此更改name
没什么区别。在这种情况下,如果您要搜索与HashMap
中放入的完全相同的Person
实例,则默认实现可确保您的密钥可以在Map
中找到。