一、HashMap默认装载因子是多少?
0.75
二、调用构造方法的时候会创建Node数组吗?
不会
三、元素的哈希值是怎么算出来的?
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
通过元素的哈希码进行一定的位运算得到的
四、HashMap Node中的数据什么情况使用链表存储?什么时候用红黑树存储?
当某个Node中的链表长度大于8且数组长度大于64时才会转成红黑树存储,
否则使用链表存储
五、当发生哈希冲突时如何处理?
如果哈希code相同,则新结点替换旧结点。
否则,如果Node是链表时,则把新结点插在链表的尾部
六、什么时候扩容?
元素的数量大于数组大小(默认16)*装载因子(默认0.75)会扩容,扩容后的容量为原来的2倍。
七、最大容量是多少?
MAXIMUM_CAPACITY = 1 << 30
八、容量一定是2的多少次幂吗?
是的。
例如,
HashMap<String,String> map = new HashMap<>(17);
构造这个Map时,构造方法会通过 this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
把threshold设置为32.
当首次往Map中put元素时,会调用resize()进行扩容,
通过 else if (oldThr > 0) // initial capacity was placed in threshold
newCap = oldThr;
这个语句,把新的容量设置为32。
当下次再进行扩容时,旧的容量已经大于0,将通过如下逻辑将容量和threshold翻倍
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
九、key可以为空吗?
可以。ConcurrentHashMap key不能为空