HashMap底层原理

没有压力的生命就会黯淡。你好我是梦阳辰,期待与你相遇!

01.什么是哈希?

核心理论: Hash也称散列、哈希,对应的英文都是Hash。基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。

Hash的特点:
1.从hash值不可以反向推导出原始的数据

⒉输入数据的微小变化会得到完全不同的hash值,相同的数据会得到相同的值

3.哈希算法的执行效率要高效,长的文本也能快速地计算出哈希值

4.hash算法的冲突概率要小

由于hash的原理是将输入空间的值映射成hash空间内,而hash值的空间远小于输入的空间。根据抽屉原理,一定会存在不同的输入被映射成相同输出的情况。

抽屉原理:桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面放不少于两个苹果。

这一现象就是我们所说的“抽屉原理”。

散列表整合了数组和链表的优点。

02.HashMap原理

在这里插入图片描述

元素超过64,链表长度超过8就会树化。

在这里插入图片描述
在这里插入图片描述

引入红黑树,是为了解决链表长度过长,效率较低。

03.tableSizeFor方法

返回一个大于等于当前值容量的一个2次方的值。

底层有tableSizeFor方法,确保容量为2的次方

static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0
比如7的二进制是111,7>>>2表示右移2位,变成001,即为1

创建的数组长度值一定为2的次方。

当数组长度不为2的n次幂 的时候,hashCode 值与数组长度减一做与运算 的时候,会出现重复的数据,因为不为2的n次幂 的话,对应的二进制数肯定有一位为0 ,这样,不管你的hashCode 值对应的该位,是0还是1 ,最终得到的该位上的数肯定是0,这带来的问题就是HashMap上的数组元素分布不均匀,而数组上的某些位置,永远也用不到,如下图所示:
在这里插入图片描述

04.putVal方法

扰动函数让key的hash值的高16位也参与路由运算。
异或运算。

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在jdk1.8之前是插入头部的,在jdk1.8中是插入尾部的。

05.reSize方法

为什么需要扩容?
为了解决哈希冲突导致的链化影响查询效率的问题,扩容会缓解该问题。
在这里插入图片描述
在这里插入图片描述

Great minds have purpose, others have wishes.

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值