jdk1.8之后hashmap底层结构
jdk1.8之后,是哈希表数据结构,也可以说是数组+链表或红黑树,下图是没有添加数据的一个hashmap。
现在开始添加数据,看下面具体步骤
put操作
如下,我们来简单看看hashmap的put源码,关注putVal的前三个参数就行,当增加一对key、value的时候,底层会做哈希运算,hash(key),它会将你的key映射到上面数组的某个位置。
1. 如果这个位置没有值,直接插入。
2. 如果有值,代表发生了哈希冲突,这时候又要分两种情况,key相同就覆盖,不同就放入链表或红黑树,也许你不懂为什么是链表或者红黑树,接着往下看。
public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}
如下图,红色是我们插入的值,4个连续红色的就是发生了哈希冲突,key不相同,就形成了链表。这里链表的插入是尾插法
而当链表的长度>=8并且数组长度>=64后,这个链表才会转化为红黑树。转化操作看起来很麻烦费事,其实大大提升了hashmap的查找效率,假如我们在数据量大的时候不转为红黑树,一条链表挂得很长,那么查该链表里面某个数据的时间复杂度就是O(n),如果是红黑树,时间复杂度就是O(log n)。
get操作
例如hashmap.get(key),此时底层就会根据key计算哈希值,找到底层数组下标位置,如果是链表,依次对比key是否一样。如果是红黑树,根据红黑树进行查找对比。
jdk 1.7 之前hashmap底层原理
只说和1.8之后不一样的地方。
1. 底层是数组加链表,也就是拉链法,没有红黑树。
2. 链表的插入是头插法