HashMap源码解析(初始化及put方法)

HashMap基于数组+链表的结构实现,内部使用Node作为Entry。在put时,通过hashcode运算确定存储位置,避免哈希冲突。当链表长度达到8时,转换为红黑树。初始化时,如果数组为空,会创建默认容量的数组。put过程包括:检查数组位置、处理key冲突、判断是否转为红黑树。合理的初始容量可以优化性能,避免过多的扩容和重hash操作。
摘要由CSDN通过智能技术生成

Map初始化及put过程:

首先通过默认的构造方法在堆内存中开辟一块地址。并指定默认负载因子。
HashMap底层是一个数组+链表的结构。即一个线性数组结构,Map中有一个内部Entry接口,HashMap在自己的静态内部类Node中实现了它。有三个属性key/value/next。即键值和下一指向。
当调用map的put方法时,调用hashmap的getNode方法,它返回一个Node节点。

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

再往下看,如果key不为空,通过key算出散列值,并赋给h,h再与右移16位的h异或。这种操作是为了加大hashcode低位的随机性。散列值是一个int类型的16进制数,共32位。在底层需要通过该散列值算出所在数组下标,以确定存储位置。但Hashmap默认容量16,32位散列值太大,不能直接拿来计算,因此要先对数组长度取模,得到余数,再用于计算下标。取模还是通过一个indexFor函数实现的,它将散列值和数组长度做与。高位清空,保留低位,如果数组长度还是取16的话,那取模之后只保留4位了。但如果只取最后几位,哈希碰撞可能很严重,且如果散列本身做的不好,分布上成等差数列,会产生规律性。这是就通过下面的扰动函数解决问题。先右移16位,在与自身异或。混合原始哈希码的高位和低位,以此来加大低位的随机性。
而且这一步在jdk1.7是做了4次扰动,jdk1.8简化为1次,一次就够用了,毕竟边际递减效应。
这里写图片描述
这部分的返回值即扰动后的散列值。

static final
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值