HashMap 1.8之后的解读

加入了红黑树,并且对hash函数加以改进

b).每个对象都有一个hashcode,但是hashmap并没有直接使用它,而是使用hash函数进行了一次处理,处理完之后用indexfor求出所在的位置。

对于1.7的hash,纯粹是数学计算,不用理会,可以看1.8的hash优化

c).1.8的的hash优化

 static final int hash(Object key) {
int h; // 下面是将低16位和高16位做个异或运算,高16位保持不变
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

因为key的原始哈希值很大(int类型,32位),而数组很小,所以如果直接用的话,高位信息将会丢失,会增大冲突的可能性。所以java要做一个优化,将key原始的哈希值低16位和高16位做异或运算,不浪费高位资源,使得低位更随机,详细论述参看:

https://www.cnblogs.com/zhengwang/p/8136164.html

https://www.zhihu.com/question/62923854/answer/204445142

d).对于indexfor  

1 static int indexFor(int h, int length) {
2 return h & (length-1);
3 }

   h%length,当length是2的次幂时,等价于h & (length-1),因为length为2的次幂时,length - 1的低位全是1,高位全是0,位与运算保留hash值的低位,即对应的余数.位运算要比模运算要快

  冲突会少,让数据均匀分布,因为16-1的二进制是1111(掩码)低位的四个全部保留,而15-1的二进制1110,只保留了低位的前三位,丢失了哈希值信息,可以参考下面实验

  

  图片来自https://blog.csdn.net/qq_27093465/article/details/52207152

3.常见面试题

https://blog.csdn.net/u012512634/article/details/72735183

好文:http://www.importnew.com/28263.html

1.8详解:https://www.cnblogs.com/yangming1996/p/7997468.html

1.8 hash函数和tableSizeFor的理解:https://blog.csdn.net/fan2012huan/article/details/51097331

理解HashMap:

1.底层结构(数组+ 链表  / 数组+ 链表+ 红黑树  Entry数据结构)

  用红黑树可以加快检索速度

2. put方法:

  -- 解决冲突的方法(拉链法)     其他方法(开放地址法/再散列法)

  -- hashcode()和equals的理解

    https://github.com/CyC2018/CS-Notes/blob/master/notes/Java%20%E5%9F%BA%E7%A1%80.md#hashcode

  -- 理解indexfor:

    1)HashMap的桶的个数为什么是2的幂

    2)为什么要rehash

3.扩容机制以及并发条件下hashmap成环问题

  https://blog.csdn.net/u011305680/article/details/80511885

  -- jdk7 总结

    创建一个新的数组newTable,容量是oldTable的一倍
    遍历oldTable,拿到每个链表
    遍历链表,头插法插入newTable

  -- jdk8 高低位链表

    hash值h二进制为 0010 1100 1111 0001 1110 1110
    旧容量为length=16,二进制为 0001 0000

    两个相与,可以计算出低位第五位的二进制数是否是1,从而确定高低链

  -- 成环问题  因为1.7是头插法,而头插法会导致成环    https://coolshell.cn/articles/9606.html   hashmap1.8不会成环,因为尾插,但并发条件下还是用concurrenthashmap的好

      

4.键值允许为null,默认index=0

5.hashtable,hashmap,concurrenthashmap简要对比https://www.cnblogs.com/heyonggang/p/9112731.html

6.concurrenthashmap好文https://www.cnblogs.com/shan1393/p/9020564.html

7.  1.7和1.8的不同

  -- 底层结构

    1.7 数组加链表; 1.8 是数组加链表,再加红黑树(数量为8转成红黑树,数量为6转成链表)

  -- hash方法

    1.8的更加简单,高位右移十六位再做异或

  -- 扩容机制的不同

    1.8 不会成环(尾插)

·        1.8 不用再次求index(高低链表)

        -------以上是优化

  -- 扩容的条件

    1.7 :size > threshold && bucket[hashIndex] != null

    1.8:size > threshold

  -- 1.8中的扩容包含了初始化

  -- 为什么不用AVL  https://blog.csdn.net/hustyangju/article/details/27214251?utm_source=tuicool

8 concurrenthashmap:

  1.8相当于放弃了segment结构,直接使用数组的第一个对象作为该链表的锁。

HashMap源码解读的更多相关文章

  1. HashMap源码解读(转)

    http://www.360doc.com/content/10/1214/22/573136_78188909.shtml 最近朋友推荐的一个很好的工作,又是面了2轮没通过,已经是好几次朋友内推没过 ...

  2. HashMap源码解读(JDK1.7)

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  3. jdk 8 HashMap源码解读

    转自:https://www.cnblogs.com/little-fly/p/7344285.html 在原来的作者的基础上,增加了本人对源代码的一些解读. 如有侵权,请联系本人 这几天学习了Has ...

  4. 深入理解JAVA集合系列一:HashMap源码解读

    初认HashMap 基于哈希表(即散列表)的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键. HashMap继承于AbstractMap,实现了Map.Cloneab ...

  5. hashMap 源码解读理解实现原理和hash冲突

    hashMap 怎么说呢. 我的理解是 外表是一个set 数组,无序不重复 . 每个set元素是一个bean ,存着一对key value 看看代码吧 package test; import jav ...

  6. HashMap源码解读(jdk1.8)

    1.相关常量 默认初始化容量(大小) static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 最大容量 static final int M ...

  7. HashMap 源码解读

    HashMap在JDK1.7和1.8中有了很大的改变,空闲时间对HashMap做了一点点的研究. HashMap是一种数组和链表结合的数据结构,我们每次new一个HashMap时,都会构造出一个长度为 ...

  8. java集合之HashMap源码解读

    源自:jdk1.8.0_121 HashMap继承自AbstractMap,实现了Map.Cloneable.Serializable. HashMap内部是由数组.链表.红黑树实现的 变量 // 默 ...

  9. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

随机推荐

  1. ubunta_django_install

    sudo apt-get install python-pip sudo apt-get install python-virtualenv #安装本地虚拟环境管理工具 mkdir ~/django ...

  2. 单例设计模式 --c#

    单例设计模式:在单例设计模式中我们要保持对象始终是唯一的 参考代码: class SingleObject { private SingleObject() { } private static Si ...

  3. PKUWC2018 5/6

    总结: D1T1T2的思路较为好想,D1T3考试时估计是战略放弃的对象,D2T1思路容易卡在优化状态上(虽然明显3n的状态中有很多无用状态,从而想到子集最优,选择子集最优容易发现反例,从而考虑连带周边 ...

  4. Linux的简单介绍.

    Linux操作系统概述: Linux是基于Unix的开源免费的操作系统,由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境.Linux是由Linux Torvalds(林纳斯·托瓦兹)起初开发 ...

  5. javax.servlet.ServletException: Servlet.init() for servlet springmvc threw exception

    type Exception report message Servlet.init() for servlet springmvc threw exception description The s ...

  6. python字符格式化

    使用%格式化字符串 字符串格式化使用格式化操作符即百分号. 在%号的左侧放置一个字符串(格式化字符串),而右侧则放置希望格式化的值. In [17]: name = "wxz" I ...

  7. Windows下用cmd命令实例讲解yii2.0 的控制台定时任务

    Yii中的资源是和Web页面相关的文件,可为CSS文件,JavaScript文件,图片或视频等,资源放在Web可访问的目录下,直接被Web服务器调用. 有时候有些功能需要做到计划任务中去,因此就需要y ...

  8. 免费CDN公共库——网站提速 静态资源库

    原文链接:https://blog.geekzhao.me/cdnjs.html 新浪SAE公共资源 推荐指数★★★ 支持https http://lib.sinaapp.com/js/jquery/ ...

  9. 20165211 2017-2018-2 《Java程序设计》课程总结

    20165211 2017-2018-2 <Java程序设计>课程总结 一.每周作业及实验报告博客链接汇总 预备作业1:我期望的师生关系 预备作业2:学习基础和C语言调查 预备作业3:Li ...

  10. NOIP模拟题 2017.11.6

    题目大意 给定一个大小为n的数组,从中选出一个子集使得这个子集中的数的和能被n整除. 假设开始我没有做出来,那么我就random_shuffle一下,然后计算前缀和,有一个能被n整除,就输出答案.于是 ...