解决hash冲突的几种方法_hashmap hash冲突

解决hash冲突的几种方法_hashmap hash冲突哈希表定义散列表(Hashtable,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。实现关键点hash函数hash冲突解决首先来说hash函数,java中对象都已一个hashCode()方法,那为什么还

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

哈希表定义


  • 散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。 也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。 这个映射函数称做散列函数,存放记录的数组称做散列表。

实现关键点


  • hash函数
  • hash冲突解决

hash函数
首先来说hash函数,java中对象都已一个hashCode()
方法,那为什么还需要hash函数呢?hashCode是在jdk中是有符号int类型,这个一个很大的范围,如果散列表的数组能覆盖所有int值的话,就不需要hash函数了,当然内存不允许我们维护这么大的散列表。这时我们需要hash函数将原始hashCode映射到一个很小的数组上去。
常见的做法是取模法,也是jdk中的实现方式。

  • HashMap实现

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
 static int indexFor(int h, int length) {
         return h & (length-1);
     }

第一个hash函数有人称之为“扰动函数”,第二个indexFor函数在jdk8中去掉了,函数内的代码合并到了putVal中,个人认为这两个函数合并起来是一个完整的hash函数。
h & (length-1) 这段代码的作用其实就是取模,假设数组初始化长度为16,那么length-1的结果为15,对应二进制为00001111,如果我们有一个大小为20的key,对应二进制为00010100,与运算后结果为00000100,对应十进制为4.
这里数组的长度必须为2的次幂。

由于对key进行了取模运算,所以我们知道当length=16的时候,我们会舍弃调掉key高位的值,只保留了低4位。本来int是32位,只是用低4位冲突是不是太容易发生了?
所以第一个“扰动函数”的作用出现了,这个函数将key本身高16和低16位做了异或运算。
解决hash冲突的几种方法_hashmap hash冲突

从网上找了这张图,可以解释下(h = key.hashCode()) ^ (h >>> 16) 的作用。

通过高位和低位异或之后,本来被丢弃的高位值在做取模运算的时候也能体现得到。


  • ThreadLocal.ThreadLocalMap实现

 private void set(ThreadLocal<?> key, Object value) {

            // We don't use a fast path as with get() because it is at
            // least as common to use set() to create new entries as
            // it is to replace existing ones, in which case, a fast
            // path would fail more often than not.

            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);

            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal<?> k = e.get();

                if (k == key) {
                    e.value = value;
                    return;
                }

                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            int sz = ++size;
            if (!cleanSomeSlots(i, sz) && sz >= threshold)
                rehash();
        }

其中int i = key.threadLocalHashCode & (len-1); 就是直接取模。


hash冲突避免

  • HashMap
    • 拉链法
  • ThreadLocal.ThreadLocalMap
    • 线性探测再散列
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/179087.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm全文搜索_pycharm查找快捷键

    pycharm全文搜索_pycharm查找快捷键在pycharm中如何全局搜索关键词

    2022年8月28日
    2
  • windows部署apache_win7下ftp服务器搭建

    windows部署apache_win7下ftp服务器搭建======================更新时间2019年5月6日=====================更新内容:增加操作系统及VC++的版本要求======================更新时间2019年4月19日=====================更新内容:Apache版本更新到2.4.39,修改配置文件更加简单,只需一步。原始的2.4.2…

    2025年8月24日
    7
  • git clone 慢

    git clone 慢首先:查询最新的DNS网上很多设置的IP可能不一样http://github.global.ssl.fastly.net.ipaddress.com/ 2.修改host文件:host文件在Windows的路径为C:\Windows\System32\drivers\etc最好先备份一个原文件(备份是好习惯)有记事本打开即可151.101.185.194github.global….

    2022年7月21日
    11
  • 探索衰老机制的中心环节_紫乌鸦刷新机制改了

    探索衰老机制的中心环节_紫乌鸦刷新机制改了前期准备:PC:win7X64vs2013 emwin相关:emwin5.42模拟器,emwin5.42英文手册 同一父窗口下两个控件的刷新不对父窗口进行刷新的前提下,指刷新widget1和widget2. 1.widget为 Framewin或WIndow如果两个widget为Framewin或WIndow类型,则graphic

    2022年10月14日
    4
  • tcp udp测试工具_https使用什么协议

    tcp udp测试工具_https使用什么协议目录一、网络七层与四层模型1.1OSI七层网络模型1.2TCP/IP四层概念模型二、TCP、UPD协议详解2.1TCP三次握手2.2TCP四次挥手2.3UDP协议与TCP协议对比三、HTTP、HTTPS协议详解3.1HTTP协议之请求报文3.2HTTP协议之响应报文3.3HTTPS协议详解3.4HTTP协议与HTTPS协议对比四、常见面试题一、网络七层与四层模型1.1OSI七层网络模型OSI七层模型:是ISO组织研究的一种网络互连模型,目的是为了推荐所有公司使用这个规范来控制网络。

    2026年2月3日
    3
  • 做饭给自己一人吃,如何最快速,且营养有保证?

    做饭给自己一人吃,如何最快速,且营养有保证?二六 ,又土又木的设计师792 人赞同作为一个长期一个人的单身狗,这个我非常有经验啊。下面介绍一下我这三四年独居生活总结下来的经验。1.周末在家多屯点儿菜放冰箱,按照每顿饭一荤一素一个汤的组合,大致估摸着买菜。肉类肯定是要一些的,肉买多了不要紧可以速冻放的久些。蔬菜就不能买多了,绿叶的尤其不能多,因为它两三天就蔫了。所以以两天内的绿叶菜再搭上一天的瓜类豆类蔬菜为宜。2.

    2022年7月15日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号