date: 2020-08-21 16:48:00

updated: 2020-08-21 16:52:00

HashMap 中的哈希值计算问题

1. hash 计算

JDK1.8

HashMap源码

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

右移16位相当于将高16位移入到低16位,再与原hashcode做异或计算(位相同为0,不同为1)可以将高低位二进制特征混合起来 => 高16位没有发生变化,但是低16位改变了

拿到的hash值会参与hashmap中数组槽位的计算,计算公式:(n - 1) & hash,假设数组初始槽位16个,那么槽位计算如下:

高区的16位很有可能会被数组槽位数的二进制码锁屏蔽,如果我们不做刚才移位异或运算,那么在计算槽位时将丢失高区特征

虽然丢失了高区特征,不同hashcode也可以计算出不同的槽位来,但是如果两个hashcode很接近时,高区的特征差异可能会导致一次哈希碰撞。

2. 使用异或运算的原因

异或运算能更好的保留各部分的特征,如果采用 & 运算计算出来的值会向0靠拢,采用 | 运算计算出来的值会向1靠拢

3. 为什么槽位数必须使用2^n / 为什么要 &length-1

为了让哈希后的结果更加均匀,减少hash碰撞

4. 扩容后Hash值计算

length * 2,即新增的bit位是1,在 (n - 1) & hash 时,只需要判断新增加的这一个bit位,如果是0的话,说明索引不变,如果变成1了,索引变成 原索引+扩容前的容量大小

HashMap 中的哈希值计算问题的更多相关文章

  1. HashMap中的哈希函数分析

    首先我们要知道,在理想情况下的哈希表中,哈希函数生成的哈希值是value在数组中的下标,其范围是分布于负无穷到正无穷的整个实整数轴的.而在现实情况下,是不可能存在这么大的一个数组的.接下来分析Hash ...

  2. geotrellis使用(十六)使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题

    Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 问题探索 采样说明 实现方案 总结 一.前言     ...

  3. 如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?

    如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗? ----答案是 可以 原因: 在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了h ...

  4. 关于HashMap中的负载因子

    这两天在看HashMap的时候,被负载因子float loadFactor搞得很晕,经过一天的研究,最后理出了自己的一点个人见解. 在HashMap的底层存在着一个名字为table的Entry数组,在 ...

  5. HashMap/HashSet,hashCode,哈希表

    hash code.equals和“==”三者的关系 1) 对象相等则hashCode一定相等: 2) hashCode相等对象未必相等. == 是比较地址是否相等,JAVA中声明变量都是引用嘛,不同 ...

  6. hashmap实现及哈希冲突

    原文: https://www.cnblogs.com/peizhe123/p/5790252.html HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置.当程序执行 map. ...

  7. [Java]HashMap实现与哈希冲突,与HashTable的区别

    对于 Map ,最直观就是理解就是键值对,映射,key-value 形式.一个映射不能包含重复的键,一个键只能有一个值.平常我们使用的时候,最常用的无非就是 HashMap. HashMap 实现了 ...

  8. Java集合类中的哈希总结

    JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...

  9. Java中的哈希

    Java中的哈希 前言 在开发中经常用到HashMap.HashSet等与哈希有关的数据结构,一直只知道这些哈希的数据结构不保证顺序,不清楚具体什么情况.所以在这里大致总结一下.   Java的Has ...

随机推荐

  1. robotframework获取Token

    公司做接口自动化,但是其他接口调用都需要传入token,所以首要目标是把token读取出来. 需要清楚以下内容: 1.登录使用post请求 2.https协议,且登录后需手工验证SSL证书,默认处于不 ...

  2. Redis中String类型的相关命令操作

    String append 如果key已存在,则直接在value追加值,如果key不存在,则会插件一个新的value为空的key,然后在追加 127.0.0.1:6379> set name l ...

  3. RCTF 2019 web

    写在正文前 神仙题,压根不会. 听说跟着神仙的思路走一遍印象会深点,Just mo it .2333 正文 nextphp 整体思路:phpinfo得知存在preload.php文件,并与opcach ...

  4. 【SCOI2016】背单词

    P3294[SCOI2016]背单词 [提示] 这道题大概是告诉我们,让我们用一堆n个单词安排顺序,如果当前位置为x,当前单词的后缀没在这堆单词出现过,代价就为x,这里的后缀是原意,但不算自己(不算本 ...

  5. C# Redis分布式锁 - 单节点

    为什么要用分布式锁? 先上一张截图,这是在浏览别人的博客时看到的. 在了解为什么要用分布式锁之前,我们应该知道到底什么是分布式锁. 锁按照不同的维度,有多种分类.比如 1.悲观锁,乐观锁; 2.公平锁 ...

  6. 【基础】dp系列1

    序列双段最大子段和问题 (也许很水但蒟蒻刚刚学dp就来记录一下) 题目链接 题意就是求序列中的任意两段的最大子段和最大. 我们先预处理出来前缀和,方便求最大子段和. 对于每一个i都求一遍1到i的最大子 ...

  7. Android高级控件(下)

    计时器(Chronometer) getBase() 基准时间 setFormat() 设置显示格式 start() 开始计时 stop() 停止计时 setOnChronometerListener ...

  8. JavaScript innerTHML和createElement效率对比

    前言: 在DOM节点操作中,innerTHML和createElement都可以实现创建元素.它们实现的功能类似,但是效率却相差很大.本文分别统计用innerTHML字符串拼接方式.innerTHML ...

  9. CDH5部署三部曲之一:准备工作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. Python+Appium自动化测试(12)-通过坐标定位元素

    在使用appium做app自动化测试的过程中,可能会遇到元素的属性值不是唯一的情况,导致不能通过find_element_bi_xx()方法定位元素,这个时候我们就可以通过坐标来定位元素. 1,通过绝 ...