美文网首页
HashMap 1.7和1.8区别

HashMap 1.7和1.8区别

作者: 尼码 | 来源:发表于2020-06-02 15:59 被阅读0次

HashMap 1.8和1.7 扩容图解

1.HashMap的数据结构:

在jdk1.8之后的改变主要目的是提高查找效率。

数组的每个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单链表中。

在1.8之后entry数组变成了node节点数组,同样有key,value,hash 和 next 这四个属性,不过,Node 只能用于链表的情况,红黑树的情况需要使用 TreeNode。

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

2.put方法:

①在key的hashCode相等,且key也相同的情况下,HashMap在执行put操作的时候,会进行覆盖操作,新值将覆盖旧值,所以最后输出为"{Aa=def}"。

②在key的hashCode相等,但key不相同(如"Aa"与"BB")的情况下,HashMap在执行put操作的时候,就会进行链表式存储,并且采用的是头插法,即新值处于链表头,最开始的值处于链表尾。

2.扩容机制

扩容的原因:hashMap的默认大小是16,当容量达到负载因子0.75时,会触发扩容机制(transfer方法),原数组的2倍。

jdk1.7时扩容时会执行transfer()方法:

创建一个新的Entry空数组,长度是原数组的2倍.

遍历原Entry数组,重新reHash到新的数组中,因为长度改变,Hsah的规则也会改变。

使用头插法,从头部插入数据。

触发了扩容后 1.7 是先扩容后插入新值的,1.8 先插值再扩容

jdk1.8时扩容时会执行reSize()方法:

创建的不是Entry数组,而是一个Node节点数组

会使用尾插法,插入数据。

让我们回顾一下Hash公式: 

index = HashCode(Key) & (Length - 1)

3.并发下的不安全性

两个线程同时执行了put()操作,并进入了transfer()环节,可能造成闭环,导致在get时会出现死循环。

4.与HashTable的比较:

Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map,Cloneable, Serializable接口。

在put方法上加上synchronized关键字。

数组+链表 的数据结构

5.HashMap与ConcurrentHashMap的比较

hashMap可以存(null,null),null的k允许存在一个。ConcurrentHashMap不允许k有null出现,否则回报控指针错误

6.HashMap为什么使用红黑树而不是AVL树

AVL树和红黑树有几点比较和区别:

(1)AVL树是更加严格的平衡,因此可以提供更快的查找速度,一般读取查找密集型任务,适用AVL树。

(2)红黑树更适合于插入修改密集型任务。

(3)通常,AVL树的旋转比红黑树的旋转更加难以平衡和调试。

总结:

(1)AVL以及红黑树是高度平衡的树数据结构。它们非常相似,真正的区别在于在任何添加/删除操作时完成的旋转操作次数。

(2)两种实现都缩放为a O(lg N),其中N是叶子的数量,但实际上AVL树在查找密集型任务上更快:利用更好的平衡,树遍历平均更短。另一方面,插入和删除方面,AVL树速度较慢:需要更高的旋转次数才能在修改时正确地重新平衡数据结构。

(3)在AVL树中,从根到任何叶子的最短路径和最长路径之间的差异最多为1。在红黑树中,差异可以是2倍。

(4)两个都给O(log n)查找,但平衡AVL树可能需要O(log n)旋转,而红黑树将需要最多两次旋转使其达到平衡(尽管可能需要检查O(log n)节点以确定旋转的位置)。旋转本身是O(1)操作,因为你只是移动指针。

部分参照:https://www.jianshu.com/p/003256ce41ce

相关文章

  • 【16】 hashmap

    hashmap 1.7 和1.8的区别 hashmap全家桶 hashmap 源码解析 hashmap hashm...

  • HashMap理解

    hashmap在jdk1.7和1.8上是有区别的,在1.7上是数组+链表的形式,在1.8上是数组+链表+红黑树的形...

  • HashMap 1.7 和1.8区别

    一、数据结构区别 HashMap 1.7 使用数组+链表HashMap 1.8 使用Node数组+链表+红黑树(当...

  • HashMap - 1.7 1.8区别

    HashMap 1.7/1.8中最大的区别就是: 1) 1.8中链表超过长度后使用红黑树; 2) 将1.7 中的H...

  • 阿里1688一面面经

    1、自我介绍 2、讲讲能体现自己能力的项目经历 3、hashMap 1.7和1.8区别 4、hashmap是线程安...

  • Android HashMap 1.8 源码分析

    前言 HashMap 1.8 的数据结构是什么样子的 ? HashMap 1.7 和 1.8 插入数据有什么不同 ...

  • Java并发(06)ConcurrentHashMap详解

    ConcurrentHashMap是实现了线程安全的HashMap,在JDK1.7和1.8中实现的原理有所区别 J...

  • Hashmap的结构,1.7和1.8有哪些区别

    实面试题之:Hashmap的结构,1.7和1.8有哪些区别 不同点: (1)JDK1.7用的是头插法,而JDK1....

  • 深入理解-HashMap源码解读

    注意:Java1.7和Java1.8中的HashMap实现有较大改动 Java1.7 HashMap 标记接口Cl...

  • Java 1.8 HashMap小结

    关于JDK1.6、1.7、1.8三个版本,HaspMap的实现是有区别的,特别是1.8,对hashmap的结构进行...

网友评论

      本文标题:HashMap 1.7和1.8区别

      本文链接:https://www.haomeiwen.com/subject/ftguzhtx.html