`
darrenzhu
  • 浏览: 782516 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

为什么HashMap容量一定要为2的幂呢?

阅读更多
原文链接:https://blog.csdn.net/wanghuan220323/article/details/78242449
做为面试常考的问题之一,每次都答的模模糊糊,有必要了解一下,首先来看一下hashmap的put方法的源码

public V put(K key, V value) { 
        if (key == null)                 
            return putForNullKey(value);     //将空key的Entry加入到table[0]中 
        int hash = hash(key.hashCode());     //计算key.hashcode()的hash值,hash函数由hashmap自己实现 
        int i = indexFor(hash, table.length);//获取将要存放的数组下标 
        /*
         * for中的代码用于:当hash值相同且key相同的情况下,使用新值覆盖旧值(其实就是修改功能)
         */ 
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {//注意:for循环在第一次执行时就会先判断条件 
            Object k; 
            //hash值相同且key相同的情况下,使用新值覆盖旧值 
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
                V oldValue = e.value; 
                e.value = value; 
                //e.recordAccess(this); 
                return oldValue;//返回旧值 
            } 
        } 
         
        modCount++; 
        addEntry(hash, key, value, i);//增加一个新的Entry到table[i] 
        return null;//如果没有与传入的key相等的Entry,就返回null 
    } 

    /**
     * "按位与"来获取数组下标
     */ 
    static int indexFor(int h, int length) { 
        return h & (length - 1); 
    } 

hashmap始终将自己的桶保持在2的n次方,这是为什么?indexFor这个方法解释了这个问题

大家都知道计算机里面位运算是基本运算,位运算的效率是远远高于取余%运算的

举个例子:2^n转换成二进制就是1+n个0,减1之后就是0+n个1,如16 -> 10000,15 -> 01111

那么根据&位运算的规则,都为1(真)时,才为1,那0≤运算后的结果≤15,假设h <= 15,那么运算后的结果就是h本身,h >15,运算后的结果就是最后四位二进制做&运算后的值,最终,就是%运算后的余数。

当容量一定是2^n时,h & (length - 1) == h % length

分享到:
评论

相关推荐

    HashMap的容量为什么必须是2的幂?

    并且如果HashMap中元素的个数大于等于阈值并且根据key的哈希值和数组长度减一做按位与运算获取的数组下标位置元素非空,则需要扩容,扩容后容量是原来的2倍,也仍然是一个2的幂,那么HashMap为什么这样来做呢?...

    HashMap-面试必过

    14.HashMap 的长度为什么是2的幂次方? 15.HashMap 与 HashTable 有什么区别? 16.如何决定使用 HashMap 还是 TreeMap? 17.HashMap 和 ConcurrentHashMap 的区别? 18.ConcurrentHashMap 和 Hashtable 的区别?

    JAVA hashmap 负载因子为什么是0.75,官方解释

    java hashmap 扩容因子为什么是0.75,官方给出的解释

    HashMap源码粗略解读(面试必问)

    3、HashMap的数组大小为什么一定要是2的幂 4、HashMap为什么是线程不安全的 5、Java7到Java8做了哪些改进 1、HashMap的默认容量 从HashMap的构造函数说起。 initialCapacity表示的是初始化的容量,默认是1&lt;&lt;4...

    HashMap面试总结.docx

    你为什么要用HashMap? 1.解决问题需要的数据结构是一种键值对的数据结构 2.HashMap是线程不安全的,其速度比较快 3.HashMap在存储key的值时,允许为NULL 4.对于输入数据的顺序与输出数据的顺序没有特别要求(如果有...

    【并发】为什么HashMap是线程不安全的?

    3.为什么hashmap不安全 why 3.1 插入HashMap.put 3.1.1 HashMap 在扩容的时候 3.2 HashMap 在删除数据的时候 0.背景 经常会看到说HashMap是线程不安全的,ConcurrentHashMap是线程安全的等等说法,不禁有个疑问,...

    集合常见面试题

    hashmap的数组长度为什么要保证是2的幂? 如何用LinkedHashMap实现LRU? 如何用TreeMap实现一致性hash? ConcurrentHashMap是如何在保证并发安全的同时提高性能? ConcurrentHashMap是如何让多线程同时参与扩容? ...

    关于如何解决HashMap线程安全问题的介绍

    HashMap为什么是线程不安全的?如何解决HashMap的线程不安全问题?

    HashMap原理.docx

    HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了...而Hashtable则不能(原因就是equlas()方法需要对象,因为HashMap是后出的API经过处理才可以)2、HashMap的工作原理是什么?

    hashmap 实例

    hashmap实例 hashmap实例hashmap实例hashmap实例

    HashMap介绍和使用

    HashMap介绍和使用

    怎样遍历一个HashMap?

    可以通过2种方法遍历HashMap &lt;br&gt;Map map = new HashMap(); &lt;br&gt;for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { &lt;br&gt; Map.Entry entry = (Map.Entry) iter.next(); &lt;br&gt; Object ...

    hashmap面试题_hashmap_

    hashmap相关的面试题

    HashMap部分源码分析

    HashMap数据结构,HashMap的构造方法,HashMap的put,HashMap的get

    HashMap存放.doc

    HashMap存放.doc

    Hashmap详解

    Hashmap详解

    面试题之详解HashMap

    文章目录1.HashMap长度为什么是2的幂次方2.HashMap多线程操作导致死循环问题3.HashMap的底层实现4.扩容机制 1.HashMap长度为什么是2的幂次方 我们利用HashMap的hash对数组长度进行取模运算得到数组下标再存放到对应...

    Javascript实现和操作HashMap

    Javascript实现和操作HashMap,压缩包里面有hashmap定义和操作的例子

    HashMap排序

    hashMap排序,hashmap使用还是比较频繁。这时自己写的一个实现hashmap排序的例子

    HashMap在put数据时是如何找到要存放的位置的?.docx

    分析HashMap在put数据时是如何找到要存放的位置的,对决定位置的hashCode计算方法进行详细解释,分析为啥要用高低16位异或运算,以及数组长度是如何影响元素存放位置的

Global site tag (gtag.js) - Google Analytics