美文网首页
HashMap扩容大小为什么是2的幂

HashMap扩容大小为什么是2的幂

作者: 维特无忧堡 | 来源:发表于2018-07-19 23:54 被阅读0次

1、前言

  在回答这个问题之前,我们可以回顾一下HashMap的存取过程,当执行putVal的操作的时候,

  • 首先检查大小,看是否需要扩容(默认元素超过最大值的0.75时扩容),如果需要扩容就进行扩容

  • 然后计算出key的hashcode,根据hashcode定位数值所在的bucketIndex

  • 如果该位置上没有元素,就直接插入,结束

  • 如果该位置上有元素就使用equal比较是否相同

  • 如果key相同就把新的value替换旧的value,结束

  • 如果key不同,就继续遍历,找到根节点,如果没找到key的话,就构造一个新的节点,然后把节点插入到链表尾部,表示put成功(jdk 1.8 之后链表长度超过阈值就会转化为红黑树)

2、详解

  好了,一个put操作就这样完成了,按照我们理想的状况,hashMap的存取就是O(1),也就是直接根据hashcode就可以找到它,每个bucket只存储一个节点,链表指向都是null,这样就比较开心了,不要出现一个链表很长的情况。

  所以我们希望它能分布的均匀一点,如果让我们设计的话,我们肯定是直接对长度取模-----hashcode % length,但HashMap的设计者却不是这样写的,它写成了2进制运算,如下:

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

index = (n - 1) & hash

  为什么设计成(n - 1) & hash 这样呢?在 n 为 2次幂的情况下时,(n - 1) & hash ≈ hash % n ,因为2进制的运算速度远远高于取模,所以就使用了这种方式,所以要求为2的幂。

  我们可以看到它求hash的过程,将32位的hashCode值向右移动16位,高位补0,也就是只要了高16位,这是为什么呢?因为hashcode的计算方法导致哈希值的差异主要在高位,而 (n - 1) & hash是忽略了容量以上的高位的,所以 使用h >>>16就是为了避免类似情况的哈希冲突

相关文章

  • HashMap扩容大小为什么是2的幂

    1、前言   在回答这个问题之前,我们可以回顾一下HashMap的存取过程,当执行putVal的操作的时候, 首先...

  • Java集合—HashMap为什么2倍扩容

    本文转载于:原文地址:HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式[https://blog....

  • android进阶面试题

    1. HashMap为什么大小是2的幂次? 最重要的就是下边的源码,就是2的幂次: 原因就是:为了数据更加分...

  • HashMap、HashSet、TreeMap、LinkedHa

    HashMap HashMap底层实现是数组+链表。数组大小不满足时要进行扩容操作,扩容是将容量扩展为原先的2倍,...

  • 关于哈希表扩容策略选择的一点总结

    本篇哈希表的扩容策略,主要讨论扩容时如何计算扩容大小的问题。第一种方法是:扩容大小应当保持是2的幂。第二种方法是:...

  • 关于 Java 中的 HashMap 常见问题总结

    1. HashMap的大小为什么必须是2的幂次 需要注意的是,创建HashMap的时候并没有将空间开辟出来,只要当...

  • HashMap详解

    问题导入: HashMap底层数据结构,如何处理hash冲突,为何HashMap的大小要设置为2的n次幂,为什么I...

  • HashMap的初始化大小为什么是2的幂

    HashMap的初始化大小为什么是2的幂 首先看下java初始化大小的源码(代码来自jdk1.8) 我们可以看到在...

  • 面试知识点

    HashMap的源码,实现原理,JDK8中对HashMap做了怎样的优化。 HaspMap扩容是怎样扩容的,为什么...

  • java一些基础知识点

    java基础 hashmap: 1,hashmap:构成原理,扩容过程,put过程,为什么长度总是2的N次方,是否...

网友评论

      本文标题:HashMap扩容大小为什么是2的幂

      本文链接:https://www.haomeiwen.com/subject/trbxmftx.html