HashMap中Java7和Java8有什么区别呢?
下文笔者讲述HashMap中jdk1.7和jdk1.8的区别说明,如下所示
区别1:底层存储的数据结构区别 Java 7使用Entry数组+单链表的数据结构 Java 8使用Node数组+单链表+红黑树,使用此种存储结构,可将时间复杂度从O(n)变成O(logN),查询效率得到提高 区别2:Hash冲突解决方法不同 Java 7中采用头插法,新元素插入到链表头中,即新元素总是添加到数组中,旧元素移动到链表中 Java 8会优先判断该节点的数据结构式是红黑树还是链表 当是红黑树,则在红黑树中插入数据 当是链表,则采用尾插法,将数据插入到链表的尾部,然后判断是否需要转成红黑树 相关说明: 1.由于JDK7使用单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题 JDK8之后是因为加入红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。 2.头插法优点: resize后transfer数据时不需要遍历链表到尾部再插入 区别3:扩容机制不同 Java 7:在扩容resize()过程中 使用单链表的头插入方式,在线程下将旧数组上的数据 转移到 新数组上时,容易出现死循环 此时(多线程)并发运行put()操作,一旦出现扩容情况,则容易出现环形链表,从而在获取数据、遍历链表时形成死循环(Infinite Loop)即死锁的状态。 Java 8:由于Java 8 转移数据操作 = 按旧链表的正序遍历链表、在新链表的尾部依次插入,所以不会出现链表 逆序、倒置的情况,故不容易出现环形链表的情况 区别4:扩容后存放位置不同 Java 7受rehash影响 Java 8调整后是原位置 or 原位置+旧容量
HashMap中使用经验
1.设置合适的初始值,避免出现扩容带来的性能消耗 2.如果使用自定义对象作为key,则需重写hashCode和equals方法 3.多线程下,笔者建议使用CurrentHashMap代替HashMap
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。