hashMap的扩容机制

capacity 即容量,默认16。 

loadFactor 加载因子,默认是0.75(3/4,与容量相乘总是整数;设置太小频繁扩容,浪费空间;设置太大碰撞的概率高,查询效率慢)

threshold 阈值。阈值=容量*加载因子。默认12。当元素数量size超过阈值时便会触发扩容。

  1. 空参数的构造函数:实例化的HashMap默认内部数组是null,即没有实例化。第一次调用put方法时,则会开始第一次初始化扩容,长度为16
  2. 有参构造函数:用于指定容量。会根据指定的正整数找到不小于指定容量的2的幂数,将这个数设置赋值给阈值(threshold)。第一次调用put方法时,会将阈值赋值给容量,然后让阈值=容量*负载因子。(因此并不是我们手动指定了容量就一定不会触发扩容,超过阈值后一样会扩容!!)
  3. 如果不是第一次扩容,则容量变为原来的2倍,阈值也变为原来的2倍(为了保持容量是2的幂次方)(容量和阈值都变为原来的2倍时,负载因子还是不变

此外还有几个细节需要注意:

  • 首次put时先会触发扩容(算是初始化),然后存入数据,然后判断是否需要扩容;
  • 不是首次put,则不再初始化,会判断当前容器的元素个数,如果大于等于阈值就要自动扩容。(先扩容后加入元素:HashMap的扩容后要再哈希计算将所有数据移至新的HashMap中,如果先插入,会多计算一次哈希值,多一次插入)
  • 容量是2的幂次方的原因:底层计算数组下标的方法是hash&(n-1)(n代表数组长度),只有n是2的幂次方的情况下,hash%n= hash&(n-1)。为了提升取模的效率,使用位运算代替了取模运算
  • HashMap的容量是无限大的吗?  不是HashMap的容量是有上限的,必须小于1<<30,即1073741824。如果容量超出了这个数,则不再增长,且阈值会被设置为Integer.MAX_VALUE( 2<<31-1 ,即永远不会超出阈值了


版权声明:本文为xinyihhh原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。