HashMap扩容

  • 扩容时机

Hash索引存在一个负载因子的概念,桶的数量*负载因子=可存储的元素个数,如果负载因子过大,会影响它的搜索效率,HashMap默认的负载因子是0.75。如果实际元素的数量大于负载因子的阈值,那就需要扩容,扩充时机是在put元素后,如果当前元素数量大于可存储的阈值,那么就会进行扩容操作。

计算索引位置

HashMap计算索引位置分为两步:
1.获取hash值;
2.计算桶的位置

  1. static final int hash(Object key) {
  2. int h;
  3. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  4. }

获取Hash值如上面代码所示,为了能够更均匀的分布,做了一次再hash操作。用哈希码的高16位和低16位做异或操作,目的是增加低位的混淆度。

  1. (tab.length -1 ) & hash

为什么HashMap获取桶的位置,没有取模操作,而是做了位运算,原因是位预算的效率更高。

HashMap、HashTable、 Collections.synchronizedMap和ConcurrentHashMap的区别

image.png