Hashmap1.7和1.8区别

简介: Hashmap1.7和1.8区别

Hashmap1.7和1.8 主要有四个区别,下面将一一说明


存储结构


在1.7版本中,HashMap使用数组+链表的方式实现,即当发生哈希冲突时,会使用链表将冲突的元素串起来。 在1.8版本中,当链表长度超过一定阈值(默认为8)时,链表会转化为红黑树,以提高查找效率。


并发性


在1.7版本中,HashMap在多线程环境下存在并发问题,可能导致死循环。 在1.8版本中,HashMap引入了"锁分段"机制,将整个存储空间分成了多个段(默认为16段),每个段独立加锁,可以提高并发性能。


扩容机制


在1.7版本中,HashMap的扩容机制是当元素个数超过容量的75%时进行扩容,扩容后容量会翻倍,把所有元素重新计算一遍位置,为了降低hash冲突。 在1.8版本中,扩容机制进行了优化,当链表长度超过一定阈值(默认为8)且元素个数超过容量的75%时,会进行链表转换为红黑树的操作,并且扩容时不再翻倍,而是以原来容量的两倍进行扩容,扩容后,不会把所有元素重新计算一遍位置。

image.png


PUT插入方式


JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法,因为JDK1.7是用单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题。但是在JDK1.8之后是因为加入了红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。


相关问题


  1. 为什么在JDK1.7的时候是先进行扩容后进行插入,而在JDK1.8的时候则是先插入后进行扩容的呢?
    其实就是当这个Map中实际插入的键值对的值的大小如果大于这个默认的阈值的时候(初始是16*0.75=12)的时候才会触发扩容
  2. 为什么在JDK1.8中进行对HashMap优化的时候,把链表转化为红黑树的阈值是8,而不是7或者不是20呢?
    如果选择6和8(如果链表小于等于6树还原转为链表,大于等于8转为树),中间有个差值7可以有效防止链表和树频繁转换。假设一下,如果设计成链表个数超过8则链表转换成树结构,链表个数小于8则树结构转换成链表,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低。
    还有一点重要的就是由于treenodes的大小大约是常规节点的两倍,因此我们仅在容器包含足够的节点以保证使用时才使用它们,当它们变得太小(由于移除或调整大小)时,它们会被转换回普通的node节点,容器中节点分布在hash桶中的频率遵循泊松分布,桶的长度超过8的概率非常非常小。所以作者应该是根据概率统计而选择了8作为阀值



相关文章
|
2月前
有关HashMap的computeIfAbsent优雅使用方式
有关HashMap的computeIfAbsent优雅使用方式
12 1
|
6月前
|
安全 Java
HashMap和Hashtable的区别
HashMap和Hashtable的区别
34 2
|
4月前
|
安全 算法
HashMap和Hashtable 的区别
HashMap和Hashtable 的区别
19 0
|
5月前
|
存储 安全 Java
HashMap和HashTable的区别
HashMap和HashTable的区别
23 0
|
10月前
|
安全
HashMap 和 HashTable 的区别
HashMap 和 HashTable 的区别
87 0
|
存储 索引
HashMap、HashTable和HashSet区别源码分析
HashMap、HashTable和HashSet区别源码分析
73 0
HashMap、HashTable和HashSet区别源码分析
|
存储 安全
HashTable 与HashMap区别
HashTable 与HashMap区别
81 0
|
存储 安全 算法
HashMap和Hashtable的联系与区别
HashMap和Hashtable的联系与区别
137 0
HashMap和Hashtable的联系与区别
|
安全 Java
HashMap与HashTable的区别
HashMap与HashTable的区别
89 0
|
存储 安全 Java
深入理解HashMap和TreeMap的区别
深入理解HashMap和TreeMap的区别