为什么HashMap中数组的初始容量是16

众所周知,HashMap内部是由一个HashCode的数组和链表组成(jdk1.8后,当链表长度达到一定的阈值后,会将链表转换成红黑树)

在初始化一个HashMap时,默认的的HashCode数组的长度是16,为什么不可以是5,10,13这样的其他数呢?

复制代码

 public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
     //计算key的hashcode
        int hash = hash(key.hashCode());
     //计算hashcode在数组里的位置
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            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);
        return null;
    }

复制代码

//用key的hashcode 按位与 上数组长度
static int indexFor(int h, int length) {
        // 任意一个数 & 15
        return h & (length-1);
    }

复制代码

void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        if (size++ >= threshold)
            // 数组长度的2倍
            resize(2 * table.length);
    }

复制代码

扫描二维码关注公众号,回复: 4811808 查看本文章

redis中有16384个slot,分配的算法和HashMap计算数组下标的算法也是一样的,有兴趣的可以看一下redis的源码~

/* 0x3FFF = 16383 ,也就是16384-1,与hashmap的hash算法不同,redis中用的是crc16算法,但不管怎样,最后也是按位与length-1,取值范围也一定是0-16383  */
return crc16(key,keylen) & 0x3FFF;

还有例如Hadoop中MapReduce时计算数据的分区,kafka中计算存储的分区时,用的是取余的算法.

例如,分区总数是3, 那么任何一个正整数对3取余,结果一定是0 1 2

郑州不孕不育医院哪家好

郑州不孕不育专科医院

郑州不孕不育专科医院

郑州不孕不育医院

猜你喜欢

转载自blog.csdn.net/qq_42564846/article/details/85987227
今日推荐