这一章节我们来讨论一下hash碰撞。
1.什么是hash碰撞?
就是两个对象的key的hashcode是一样的,这个时候怎么get他的value呢?
答案是通过equals遍历table那个位置上面的Entry链表。
2.例子
正常的例子:
-
package
import
publicclass
publicstaticvoid
new
new
);
-
);
-
);
-
new
);
-
);
-
);
-
new
);
-
);
-
new
);
-
);
-
+ map.get(person_1).getName());
-
+ map.get(person_2).getName());
-
class
privateint;
-
private;
-
publicint
return
publicvoidint
this
public
return
publicvoid
this
-
publicint
return
-
publicboolean
returnsuper
class
privateint;
-
private;
-
privateint;
-
-
publicint
+ thisthis
returnsuper
publicint
return
publicvoidint
this
public
return
publicvoid
this
publicint
return
publicvoidint
this
-
public
return + id + thisthis
-
publicboolean
+ id +
returnsuper
}
输出:
person id:1,hashCode() invoked,hashcode:443164103180
person id:2,hashCode() invoked,hashcode:443164103180
person id:1,hashCode() invoked,hashcode:443164103180
--dog_1
person id:2,hashCode() invoked,hashcode:443164103180
--dog_2
解释:
(1)上面建立两个类,然后分别在hashCode和equal方法里面加上输出语句
(2)通过输出可以看到,其实我们重写的equals方法是没有被调用的,我们只需要通过hashcode就可以定位相应的对象
hash碰撞的代码:
-
package
import
publicclass
publicstaticvoid
new
new
);
-
);
-
);
-
new
);
-
);
-
);
-
new
);
-
);
-
new
);
-
);
-
+ map.get(person_1).getName());
-
+ map.get(person_2).getName());
-
class
privateint;
-
private;
-
publicint
return
publicvoidint
this
public
return
publicvoid
this
-
publicint
return
-
publicboolean
returnsuper
class
privateint;
-
private;
-
privateint;
-
-
publicint
+ thisthis
returnthisthis
-
publicint
return
publicvoidint
this
public
return
publicvoid
this
publicint
return
publicvoidint
this
-
public
return + id + thisthis
-
publicboolean
+ id +
returnsuper
}
输出:
-
person id:,hashCode() invoked,hashcode:
-
,hashCode() invoked,hashcode:
-
2
,hashCode() invoked,hashcode:
-
1
,hashCode() invoked,hashcode:
-
--dog_2
解释:
(1)我们重写了Person,也就是key的hashCode方法,人为的产生hash碰撞现象
(2)从输出可以看出,上面的代码需要用到equals方法
回归put和get的源码;
下面是put的源码:
-
public
ifnull
return
int
int
fornull
if
-
this
return
returnnull
}
下面是get的源码:
-
public
ifnull
return
int
for
null
if
-
return
returnnull
}
大家请注意我上面注释“注意的地方”:
(1)如果是平常没有hash碰撞的时候,前面的两个hash比较再加上key的地址的比较即可,然后后出现“短路”现象,使得后的句子不再执行。
(2)但是在出现hash碰撞的情况下,前面两个条件都成立,然后必须使用最后的equals来判断对象的相等。
3.hash碰撞出现的情景?
(1)一般会出现在大的数据情况之下
(2)hashcode的生成方法唯一性较弱(比如上面的人为的生产hashcode)
总结:这一章节主要通过介绍hash碰撞再一次深入了解HashMap的工作原理。
这一章节就到这里,谢谢。