HashMap JDK 1.8 后它改了什么?
推荐一个咕泡学院的视频资源:链接:https://pan.baidu.com/s/1SmSzrmfgbm6XgKZO7utKWg 密码:e54x
先回答一下之前发布的《使用HashMap的时候小心点》同学不补充的问题,说最好说下HashMap在JDK8下是怎么解决死循环的问题的。
链表部分对应上面 transfer 的代码:
1 | Node<K,V> loHead = null, loTail = null; |
由于扩容是按两倍进行扩,即 N 扩为 N + N,因此就会存在低位部分 0 - (N-1),以及高位部分 N - (2N-1), 所以这里分为 loHead (low Head) 和 hiHead (high head)。
通过上面的分析,不难发现循环的产生是因为新链表的顺序跟旧的链表是完全相反的,所以只要保证建新链时还是按照原来的顺序的话就不会产生循环。
JDK8是用 head 和 tail 来保证链表的顺序和之前一样,这样就不会产生循环引用。
传统 HashMap 的缺点
JDK 1.8 以前 HashMap 的实现是 数组+链表,即使哈希函数取得再好,也很难达到元素百分百均匀分布。
当 HashMap 中有大量的元素都存放到同一个桶中时,这个桶下有一条长长的链表,这个时候 HashMap 就相当于一个单链表,假如单链表有 n 个元素,遍历的时间复杂度就是 O(n),完全失去了它的优势。






