HashMap的hash源码解释

HashMap里的Hash

HashMap内部维护了一个链表数组table,每个元素都是节点Node。为了解决Hash算法的冲突性,HashMap则使用了节点挂载到数组上。

下面是Node的基本属性和构造方法。

        final int hash;
        final K key;
        V value;
        Node<K,V> next;//如果有hash冲突现象,则放到下个节点一起挂载

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

 

大概长这样:

在使用put(Key,Value)的时候,会先计算出Key的哈希值hashKey,该值就是数组的索引,通过table[hashKey]则快速获得第一个节点。

如果该地方没有节点,则代表是空的,直接插入即可。

如果该地方有节点,查看Key是否相等,如果相等,那么就覆盖掉本节点,如果key不相等,则去找下个节点,并重复该步骤。

如果所有节点的key都不相等,意味着这又是一次hash冲突,则新建节点,挂载到最后。

 

在使用get(key)的时候,会计算出hashKey,通过table[hashKey]获得节点。

如果是null,则代表目前没有该节点。

如果不是空的,则查看key是否相等,如果相等,那么就把value值返回,如果key不相等,则去找下个节点,并重复该步骤。

如果所有节点的Key都不相等,则代表是null.

 


推导式分析:

假如现在内部table定长是100,而hash计算结果大都是0~20,也就是基本上所有的元素都在0~20的地方挂载着,20~80的反而寥寥无几,这就是垃圾的hash函数。

作为容器使用的hash函数应该有均匀分布的特性,要能充分利用空间,防止元素聚集,挂载太多导致查找的效率降低。

HashMap内部计算hash时,它的计算策略是和当前数组长度有关的动态hash策略,数组长度不同,键值对的Key计算出的hash也是不同的,目的都是为了保证均匀分布

HashMap默认长度是16,那如果往里面添加更多的元素,则数组会扩容,每次扩一倍,hash算法将重置,内部元素则依据新hash算法重新插入一个扩容的数组。

扩容时机在于这个参数: static final float DEFAULT_LOAD_FACTOR = 0.75f,当数组内当前元素数量达到数组长度的75%时,则会扩容,重新计算hash.

这意味着DEFAULT_LOAD_FACTOR的值越小,代表着空闲空间很多,但是挂载情况少效率高。值越大,空间利用率高,挂载情况将多。

 一般情况下DEFAULT_LOAD_FACTOR为0.5~0.75之间,HashMap默认的时0.75f

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值