码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • HashMap如何确定数组位置


    文章目录

    • 1.HashMap 底层数据结构
    • 2.元素是如何定位到数组位置的
    • 3.与(&) 、 异或(^)、或(|)
    • 4.位置计算
    • 5.这样做的好处是什么?
    • 6.总结

    1.HashMap 底层数据结构

    HashMap 底层数据结构为数组+链表+红黑树,当map去put的时候,元素先定位到数组的位置,如果有多个元素定位到了数组的同一个位置,就会生成链表,当链表长度大于8并且数组长度大于64时,会转换为红黑树。

    2.元素是如何定位到数组位置的

    先看put方法

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

    数组位置定位:
    第一步:hash运算

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

    第二步:用第一步的值与数组容量取余

    i = (n - 1) & hash
    
    • 1

    因为hashmap的容量大小是2的幂次方,所以可以通过&运算来优化%运算。例如:(16 % 5 )等价于 (16 & (5 - 1))

    在这里插入图片描述

    3.与(&) 、 异或(^)、或(|)

    位与(&) :      0 & 0 = 0      0 & 1 = 0      1 & 0 = 0       1 & 1 =1 
    
    位异或(^):     0 ^ 0 = 0      0 ^ 1 = 1      1 ^ 0 = 1       1 ^ 1 = 0
    
    按位或(|):     0  | 0 = 0     0 | 1 = 1      1 | 0 = 1       1 | 1 = 1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.位置计算

    hash = (h = key.hashCode()) ^ (h >>> 16)
    最终位置 = (n - 1) & hash

    在 Java 中,hashCode 是 int 类型,经过hash运算后得到的值也是int类型,即32 位,前16位为高位,后16位为低位。
    (h = key.hashCode()) ^ (h >>> 16) 的含义就是将hashCode的高位与低位做异或运算。

    现在假设key.hashCode = 65536(2^16) ,数组大小为n=16 ,位置计算过程如下:
    在这里插入图片描述

    所以最终得到位置1 , 即hashCode = 65536 的key,放在数组1的位置。

    5.这样做的好处是什么?

    我们试想一下,如果key.hashCode >= 65536(2^16) ,而数组的大小只有16、32、64、128 等大小(分布在低16位),如果只做取余操作,那么高16位的值其实是无法参与到运算的,那key.hashCode >= 65536的所有key都是不是都会定位到同一位置?
    让hashCode右移16位, 是让hashCode的高位也参与到取模运算中,这样就可以使得键值对分布的更加均匀。

    6.总结

    好记性不如烂笔头,知道不如做到。

  • 相关阅读:
    Java 中 List 集合取补集
    Spring系列之beanFactory与ApplicationContext
    漏刻有时数据可视化Echarts组件开发(42)渐变色的应用
    Python基础知识点总结
    <Babel> 前端语言的巴别塔
    qt判断当前日期的当月的最后一天是几号
    一个重要的问题:怎么寻找自己的终身事业呢?
    Unity 将是驱动 C# 增长的引擎吗 ?
    三十六、java版 SpringCloud分布式微服务云架构之Java 泛型
    NFC 音乐墙 (不限手机)[web 接口服务实现-折腾记录]
  • 原文地址:https://blog.csdn.net/zjy15203167987/article/details/125543956
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号