内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

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

2019-01-06 20:45 出处:清屏网 人气: 评论(0

众所周知,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);
    }

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

分享给小伙伴们:
本文标签: HashMap数组

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号