前不久去面试有面试官问我HashMap初始长度计算问题,我把我的计算方法说出来被否定了,因为口头面试也没法明确也忘了原本计算方式就忽略了。然后今天写代码需要定义长度所以特地去自我求证了下,发现并没毛病还更容易记住,所以分享给大家。最原本这个方法是我演化来的还是看的别人的有点记不清了,太过久远。
不想计算,不想优化性能的请直接设置默认16出门右转。
1.作用
Map随着元素增加,会进行多次扩容,影响性能。假如我们已经知道要添加的元素数量,创建Map对象就将容量设置到位,就可避免扩容。
2.官方算法
上源码
/**
* Implements Map.putAll and Map constructor.
*
* @param m the map
* @param evict false when initially constructing this map, else
* true (relayed to method afterNodeInsertion).
*/
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
int s = m.size();
if (s > 0) {
if (table == null) { // pre-size
float ft = ((float)s / loadFactor) + 1.0F;
int t = ((ft < (float)MAXIMUM_CAPACITY) ?
(int)ft : MAXIMUM_CAPACITY);
if (t > threshold)
threshold = tableSizeFor(t);
}
else if (s > threshold)
resize();
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
K key = e.getKey();
V value = e.getValue();
putVal(hash(key), key, value, false, evict);
}
}
}
算法其实挺明确就是初始长度 = int(元素数量/负载因子0.75) + 1,但是总不能每次定义都去+R 输入 calc 计算去吧,假设元素数量是两位数口算0.75太费劲,两位数的乘法运算谁也不是珠心算法传人。
3.简易算法
我的简易算法,初始长度 = 元素数量 + 1 + int(元素数量/3),算元素数量有几个3,相信在座的各位百位以内计算应该都很容易吧~ 这就比官方的很简单了不是。然后我再把验证的结果给你们看下。
没毛病吧~