HashMap

基础介绍

 打开JDK的API我们知道HashMap的语法特性:

1、hashMap存储的是键值对数据;

2、允许null键null值;

3、键是唯一的,值是可重复的;

4、实现非同步的,也就是线程不安全。

 知道这些,在日常应用中就可以入门了。

深入研究

 如果想更好地运用hashMap,完全掌控它,就必须了解它内部的原理结构;

这样你才可以在面对hashMap的时候更加从容自信!

结构


 

上图很好的说明了hashMap的内部结构:数组 + 链表; 其横向图块0——6代表数组,纵向图块既是链表;图块表示bucket,俗称桶,是hashMap中的基本单位。

当我们往hashMap中put元素的时候,会对键执行hashcode运算,找到bucket的位置, 然后在bucket中存储键值对。

此时我们明白了,键值对存储在一个bucket中,所以在api中通过entrySet获取的实际上是所有的bucket,bucket在代码中被entry所表示。

hash冲突


 我们知道了hashMap根据键进行hashcode找到bucket的位置,如果两个键的hashcode一样会发生什么呢?

会发生冲突,因为两个键找到的是同一个bucket,而一个bucket只能存储一个键值对,在这种情况下hashMap会对键进行equals,来确定两个键内容是否相等:

如果相等,那么就不进行存储,符合hashMap的键唯一原则;

如果不相等,hashMap就会创建一个链表来存储冲突的键值对。

这样我们知道了hashMap是怎么获取hash冲突的键值对:

当从hashMap中get时,首先通过键的hashcode找到bucket所在位置,然后使用equals获取链表中的键值对。

总结


在开发中,一般使用String、Integer这样的wrapper类来作为hashMap的键,因为它们在常量池中,是不可变的,所以hashcode和equals肯定是唯一的,不会发生hash冲突;

因此在bucket中只有一个键值对,不存在链表,从而减少了对链表的增删、遍历的性能消耗,也就提高了hashmap的性能。

总之减少hash冲突的链表,hashMap的性能才能最优。

原文地址:https://www.cnblogs.com/dahuandan/p/7045723.html