• HashMap之为什么数组初始化大小都是2的次方?


    1、为什么hashmap的数组初始化大小都是2的次方大小时,hashmap的效率最高?  

        /**
         * The default initial capacity - MUST be a power of two.
         */
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
        final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                       boolean evict) {
            Node<K,V>[] tab; Node<K,V> p; int n, i;
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
    
          ... 代码省略
        }

    执行put操作时,先通过i = (n - 1) & hash获取插入数组的坐标,n即上面的DEFAULT_INITIAL_CAPACITY,该属性的注释指出必须时2的次方大小,歪?

    en

    1.1、首先了解以下&运算 

    运算规则:0&0=0;   0&1=0;    1&0=0;     1&1=1;

    即:两位同时为“1”,结果才为“1”,否则为0

    1.2、如果DEFAULT_INITIAL_CAPACITY不为2的次方?

      假如DEFAULT_INITIAL_CAPACITY为15,那么(n - 1) & hash 就变成了 14 & hash 即 01110 & hash,因为01110的尾数为0,那么01110 & hash 不可能出现尾数为1的情况,导致table上尾数为1的位置不能存放元素,空间浪费大,使用的位置比数组长度小很多,导致碰撞的几率增大,所以hashmap的初始化大小都是2的次方。

     

     

  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    线性表——数组实现
    this指针与const成员函数
    类对象拷贝是不是赋值操作??
    你真的理解内联函数吗?
    名字查找先于类型检查:函数重载与作用域
    谈谈函数调用
    推荐形参使用常量引用:void func(const T &);
  • 原文地址:https://www.cnblogs.com/TripL/p/13345810.html
Copyright © 2020-2023  润新知