[HashMap源码学习之路]---put方法中的hash方法介绍

2023-11-18

HashMap中的put方法中的hash方法

  以下是put方法的代码:

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

  当我第一次看到这个地方的时候,首先好奇的是这个hash 方法到底干了什么,于是我点了进去,看到下边这样的东西,顿时懵了:

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

  我懵的原因是因为我看到了^16 ,这俩东西。到底是什么原因要做这样的操作呢?
  在此之前,我们需要了解hashCode 是干嘛的,在上一篇文章里,我有写过关于hashCode在HashMap中充当的作用 ,想了解的可以看这篇[HashMap源码学习之路]—hashcode的作用及数组长度为什么是2的n次幂
  首先,说一下这个数字16 ,对于我们得到的hashCode 值,它是int 类型,而int 类型,最大数转换成二进制的长度是32 位,对于它的一半是16 ,这个概念,没毛病吧?
这里写图片描述
  那上边的h>>>16 换句话说,就是将int类型右移16 位,那对于这样的操作,我们会得到这个int 类型数的一个高16 位的数。举一个小的例子,比如右移2 位,以数字11为例,转换成2进制是1011 ,它右移2 位,就是0010,具体如下:

11[十进制]  >>>2
相当于 
1011[二进制]  >>>2
1011[二进制]  >>>2 右移2位
会只剩下高2位数,即 0010[二进制]

再回到我们上边的代码,即:

(h = key.hashCode()) ^ (h >>> 16)

也就是说它这一步是将得到的hashCode值,对高16位 (右移了16位得到的),然后再与原来的hashCode 值进行了^ 运算。
这里写图片描述
  暂时再补充一点^ 的介绍,它叫做异或运算 ,关于异或运算的特点,可以看我的这个文章java中异或运算的应用,最好是百度一下这个,我也是百度的。这里只需要知道这样的特点即可:

异或的运算方法是一个二进制运算: 
  1^1=0 
  0^0=0 
  1^0=1 
  0^1=1 
  两者相等为0,不等为1. 
总之,就是这样,
n^0=n n^n=0,即任何数与0进行异或,为它本身;
两个相同的数进行异或运算,会得到0

  到了这里,基本的概念我们都理解了,再回来看我们这行代码:

(h = key.hashCode()) ^ (h >>> 16)

大家知道,我们的HashMap中的数组长度,一般默认是16 ,转换成二进制,无非也就是10000 ,总共五位二进制数,结合上一篇文章中的介绍,HashMap在存取值的时候,依赖hashCode 值,经过我们这个hash方法 处理后的值,再与数组长度减一进行与运算 确定出元素所处数组的位置,即:tab[i = (n - 1) & hash] 这样的操作,而在进行与运算 的时候,往往因为数组长度减一 这个数太小,造成整个hashCode 值的高位几乎不可能加入到运算中
  因此,为了能够让hashCode 值,高位也能参与到tab[i = (n - 1) & hash] 这样的与运算 中,所以有了这样的右移 ,而我觉得,正是因为hashCode 值是int 类型,最大为32 位,因此尽可能的右移最大让所有数加入到运算中,却又不丢失数据 的操作,那就只能是16 这个数!!!
  而异或运算^ 我理解的是,起到了打乱的作用,高16 位和低16 进行了这样的运算后,会使hash 值出现相同的情况更低,减少了hash 值的碰撞,进一步使HashMap 数据在数组中的落点更加均匀,拥有更大的利用率。关于异或运算^ 仅是我理解的这样,如果有大神觉得不对,请帮我纠错下,谢谢了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[HashMap源码学习之路]---put方法中的hash方法介绍 的相关文章

  • 【Linux学习笔记】7. Linux文件IO详解(附代码实例)

    Linux文件I O 前置知识 Linux文件I O分为系统IO和标准IO 常用于系统编程 系统I O通过文件描述符 fd 来操作文件 标准I O通过文件流 FILE 来操作文件 Linux下可以使用man命令来查看使用手册 学习和使用这些
  • 数据备份技术知识梳理(建议收藏)

    所谓数据保护技术是指对当前时间点上的数据进行备份 如果说原始数据被误删除了 可以通过备份数据找回或恢复数据 从底层来分 数据保护可以分为文件级保护和块级保护 文件级备份 文件级备份 将磁盘上所有文件通过调用文件系统接口备份到另一个介质上 也
  • 11-7 读写指定大小的字节

    1 字节 一个字节 8 位 例如在 ASCII 码表中 0000 1010 表示换行 若从十六进制角度看 则结果为 0a CLion debug 便是以十六进制查看的字节 2 读字节 fread 函数用于指定字节大小的读取 该函数可读取二进
  • 重启大法好

    在做springMVC服务器的时候 出现解析不了URL 即dispatch映射不了action的时候 1 检查springname servlet xml 2 检查web xml 3 检查注解是否错误 4 重启eclipse 5 重启电脑
  • Unity3D射线检测

    射线检测主要用于像子弹是否打中物体 捡取物品等情况 本来面向百度想找例子看看 不过没找到合适的 还是自己总结尝试吧 以下测试Unity3D版本 2017 4 2f2 射线的检测步骤如下 1 Ray 这个类为了产生一个射线 如果我们想要场景中
  • Acwing 906. 区间分组

    1 将所有区间按照左端点从小到大排序 2 从前往后处理每个区间 判断能否将其放到某个现有的组中 L i gt Max r 1 如果不存在这样的组 则开新组 然后将其放进去 2 如果存在这样的组 将其放进去 并更新当前组的Max r incl
  • cocoscreator 3.x 获取像素颜色

    const pos v2 世界坐标 const color as camera rt targetTexture readPixels pos v2 x pos v2 y 1 1 获得颜色 cc color color as 0 color
  • BeautifulSoup4(bs4)

    BeautifulSoup4是一个高效的网页解析库 可以从HTML或XML文件中提取数据 支持不同的解析器 比如 对HTML解析 对XML解析 对HTML5解析 就是一个非常强大的工具 爬虫利器 一个灵感又方便的网页解析库 处理高效 支持多
  • java 枚举应用_Java枚举应用

    JDK5 0开始引进了java Enum枚举类型 它可作为我们在编写代码时的一个技巧 有时恰恰因为它 我们能够 优雅而干净 地解决问题 在使用枚举类型时 我们所编写的枚举类都是隐式地继承于java lang Enum类 枚举类的每个成员都被
  • 报错:ImportError: XXXX.so:invalid ELF header

    运行程序遇到如下报错 原因是该路径下的 so文件与运行程序的环境不匹配 比如我在mac电脑上编译生成的 so文件 直接放到linux服务器上跑了 自然会有错误 解决的方法是在Linux环境中重新编译生成新的 so文件
  • C语言非常道 6.7

    使用结构类型 计算结构类型的大小 在上面这个程序中包含一个输入输出的头文件即可 这个位置又发现一个问题 在定义结构体的时候 数组的大小是一定要标明的 否则在计算结构体大小的时候 编译无法通过
  • C/C++ 安全编码 —— 指针与内存

    1 仿踩内存 if buf len 1 0x5A return
  • Node.js开发入门—HTTP文件服务器

    HelloWorld示例只有演示意义 这次我们来搞一个实际的例子 文件服务器 我们使用Node js创建一个HTTP协议的文件服务器 你可以使用浏览器或其它下载工具到文件服务器上下载文件 用Node js实现的HTTP文件服务器 比我在Qt
  • iOS、mac开源项目及库

    1 用来生成 3x 的图片资源对应的 2x 和 1x 版本 只要拖拽高清图到 3x 的位置上 然后按 Ctrl Shift A 即可自动生成两张低清的补全空位 当然你也可以从 2x 的图生成 3x 版本 如果你对图片质量要求不高的话 htt
  • 深入理解操作系统原理之文件系统

    一 概述 操作系统对系统的软件资源 不论是应用软件和系统软件 的管理都以文件方式进行 承担这部分功能的操作系统称为文件系统 1 文件 计算机系统对系统中软件资源 无论是程序或数据 系统软件或应用软件都以文件方式来管理 文件是存贮在某种介质上
  • flink 1.4版本flink table方式消费kafka写入hive方式踩坑

    最近在搞flink 搞了一个当前比较新的版本试了一下 当时运行了很长时间 hdfs里面查询有文件 但是hive里面查询这个表为空 后面用了很多种方式 一些是说自己去刷新hive表 如下 第一种方式刷新 alter table t kafka

随机推荐