duoduotouhenying

HashMap-为什么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); }

 

 

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

 

posted on 2019-01-06 18:47 nt杨 阅读(...) 评论(...) 编辑 收藏

分类:

JavaEE

技术点:

相关文章: