hashmap出现重复key的情况
刚刚写完hashmap的源码解读,然后在对hashhmap中使用put的时候数组的首节点覆盖,链节点不覆盖的,徘徊不解的情况下,在网上搜看到的一篇文章中的问题感到很好奇,下去特别实践实践。最后终于搞明白了。文章地址:http://blog.****.net/dandaoyi/article/details/40126429
其中代码例子:有model:Person类
package test3;
public class Person {
private String name;
private int age;
public Person(String name,int age) {
// TODO Auto-generated constructor stub
this.age=age;
this.name=name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
final int prime=33;
int result=1;
result=prime*result+age;
result=prime*result+((name==null)?0:name.hashCode());
return result;
}
@Override
public boolean equals(Object object) {
// TODO Auto-generated method stub
if (this==object) {
return true;
}if(object==null) {
return false;
}if (getClass()!=object.getClass()) {
return false;
}
Person other=(Person)object;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
{ return false;
}
return true;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "Person [name=" + name + ", age=" + age + "]";
}
}
有测试代码类:
package test3;
import java.util.HashMap;
import java.util.Map;
public class test2 {
public static void method1(){
Person p1 = new Person("xiaoer",1);
Person p2 = new Person("san",4);
Map<Person,String> maps = new HashMap<Person,String>();
maps.put(p1, "1111");
maps.put(p2, "2222");
System.out.println(maps);
maps.put(p2, "333");
System.out.println(maps);
System.out.println(p1.hashCode());
p1.setAge(5);
System.out.println(maps);
maps.put(p1, "1111");
System.out.println(p1.hashCode());
System.out.println(p1.hashCode());
System.out.println(maps);
System.out.println(maps.get(p1));
}
public static void main(String[] args) {
method1();
}
}
最后,打印的结果很有趣:
可以看出:在上图中竟然出现了相同的key,为什么?
首先在明白上面的问题的前提是你要知道一个知识点:在数组中存的是对象的引用,不是对象。
我对上面的程序debug了一遍,发现原来是因为在p1刚放进去的时候是由Person的name和age的hashcolde散列码共同构成的,但是,但是,但是,重要说3遍!由于放进去的只是对象的引用,所以当下面的p1.setAge(5); 时候所以数组中的值发生变化,也说明他本身的hashcode即hash发生变化,但是,但是,但是,重要说3遍!尽管现在他的散列码发生变化,然而他已经在hashmap数组中了,他位置没有发生变化,即意味着他现在变化后的hash的位置空着,所以对hashmap添加的时候就又添加进去,方在现在的位置上!!废话不多说,上图
第一张
第二张
第三张
第四张
好了上面的图按顺序,第一张是在setage之前的map图,第二张是setage之后的图,第三张,是put之后的图,发现在第一张和第二张中不能看hashcode,坑啦,最后只能打印出来,就有了第四张,由图可以看出来,还是符合结论的!
遗留的问题就是,上面get(p1)的到的是最后放入的结果!先放入的p1对应的结果无法获取。
好了,上面已经知道原因了,那上面问题会照成什么问题????对象存在旧的位置,而照成无法获取,不能得到,但是他有占据空间,如果有很多个这样的无用对象呢?这就是内存泄漏!!!!所以以后在涉到一系列的数组的操作的时候,都有注意对象的引用问题啦!!
好记性不如烂笔头,写给几年后的自己!!!