热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JDK7与JDK8中HashMap的区别

关于JDK7中的HashMap源码分析可移步:http:blog.csdn.netqq_17305249articledetails76877193
关于JDK7中的HashMap源码分析可移步: http://blog.csdn.net/qq_17305249/article/details/76877193
        总的来说,JDK7中的hashMap底层采用了数组+链表的数据结构实现数据存储,随着存储数据量的增大,Hash碰撞会越来越频繁。也就意味着链表会越来越长,查找效率不断降低。
        JDK8的出现解决了这个问题,对与hashMap采用了新的数据结构:数组+链表/红黑树(当链表长度达到某个阈值时,链表就转换成了红黑树)
        当链表的结点大于阈值(初始为8)时,将链表转换成红黑树
        例如JDK8中HashMap的put方法:
1
public V put(K key, V value) {
2
        return putVal(hash(key), key, value, false, true);
3
 }
4
 
5
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
6
                   boolean evict) {
7
        Node<K,V>[] tab;
8
    Node<K,V> p; 
9
    int n, i;
10
    //如果当前map中无数据,执行resize方法。并且返回n
11
        if ((tab = table) == null || (n = tab.length) == 0)
12
            n = (tab = resize()).length;
13
     //如果要插入的键值对要存放的这个位置刚好没有元素,那么把他封装成Node对象,放在这个位置上就完事了
14
        if ((p = tab[i = (n - 1) & hash]) == null)
15
            tab[i] = newNode(hash, key, value, null);
16
    //否则的话,说明这上面有元素
17
        else {
18
            Node<K,V> e; K k;
19
        //如果这个元素的key与要插入的一样,那么就替换一下,也完事。
20
            if (p.hash == hash &&
21
                ((k = p.key) == key || (key != null && key.equals(k))))
22
                e = p;
23
        //1.如果当前节点是TreeNode类型的数据,执行putTreeVal方法
24
            else if (p instanceof TreeNode)
25
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
26
            else {
27
        //还是遍历这条链子上的数据,跟jdk7没什么区别
28
                for (int binCount = 0; ; ++binCount) {
29
                    if ((e = p.next) == null) {
30
                        p.next = newNode(hash, key, value, null);
31
            //2.完成了操作后多做了一件事情,判断,并且可能执行treeifyBin方法
32
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
33
                            treeifyBin(tab, hash);//构建红黑树
34
                        break;
35
                    }
36
                    if (e.hash == hash &&
37
                        ((k = e.key) == key || (key != null && key.equals(k))))
38
                        break;
39
                    p = e;
40
                }
41
            }
42
            if (e != null) { // existing mapping for key
43
                V oldValue = e.value;
44
                if (!onlyIfAbsent || oldValue == null) //true || --
45
                    e.value = value;
46
           //3.
47
                afterNodeAccess(e);
48
                return oldValue;
49
            }
50
        }
51
        ++modCount;
52
    //判断阈值,决定是否扩容
53
        if (++size > threshold)
54
            resize();
55
        //4.
56
        afterNodeInsertion(evict);
57
        return null;
58
    }

推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 转载自:http:www.blogjava.netCarpenterLeearchive20160427430268.html总体介绍之所以把HashSet和HashMa ... [详细]
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • 本篇文章给大家分享的是有关Java中怎么对HashMap按键值排序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • 01Map集合概述A:Map集合概述:我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同a:Collection中的集合 ... [详细]
  • 手写HashMap,快手面试官直呼内行
    手写HashMap,快手面试官直呼内行-手写HashMap?这么狠,面试都卷到这种程度了?第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章:这……我当 ... [详细]
  • 在Java中有多种遍历HashMap的方法,注意Java中所有的Map类型都实现了共有的Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,Linked ... [详细]
  • Java面试 HashMap、HashSet源码解析
    本章所有源代码基于JDK1.8版本HashMap和HashSet是JavaCollectionFramework的两个重要成员,其中HashMap是Map接口的常用实现类,Hash ... [详细]
  • HashMap的介绍以及扩容为什么是2的n次幂
    本篇内容介绍了“HashMap的介绍以及扩容为什么是2的n次幂”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 将学生对象和学生的归属地通过键与值存储到map集合中。importjava.util.HashMap;importjava.util.Iterator;importjava.uti ... [详细]
  • 写这篇文章起源于一道面试题,如何将自定义的类对象作为key存储到HashMap中,即考虑怎么判断key的唯一性。首先,我们看以下HashMap中put(…)方法的源码:public ... [详细]
  • 邮件解析引擎FastMail库大功告成!
    1概述邮件解析库API完全使用面向对象技术设计,使用C++语言开发的用于邮件解析和组装的库。它提供了一些类用来解析和组装Internet邮件,如MimeMessa ... [详细]
author-avatar
热情连心锁426
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有