其他分享
首页 > 其他分享> > ArrayList、HashMap扩容

ArrayList、HashMap扩容

作者:互联网

1.ArrayList扩容

  默认容量是10,如果初始化时一开始指定了容量,或者通过集合作为元素,则容量为指定的大小或参数集合的大小。每次扩容为原来的1.5倍,如果新增后超过这个容量,则容量为新增后所需的最小容量。如果增加0.5倍后的新容量超过限制的容量,则用所需的最小容量与限制的容量进行判断,超过则指定为Integer的最大值,否则指定为限制容量大小。然后通过数组的复制将原数据复制到一个更大(新的容量大小)的数组。


2.HashMap扩容

  HashMap扩容可以分为三种情况:

  什么时候扩容:当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值---即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。

  扩容(resize)就是重新计算容量,向HashMap对象里不停的添加元素,而HashMap对象内部的数组无法装载更多的元素时,对象就需要扩大数组的长度,以便能装入更多的元素。当然Java里的数组是无法自动扩容的,方法是使用        一个新的数组代替已有的容量小的数组,就像我们用一个小桶装水,如果想装更多的水,就得换大水桶。 

HashMap中的变量

首先要了解HashMap的扩容过程,我们就得了解一些HashMap中的变量:

 

HashMap的构造函数

HashMap的构造函数主要有四个,代码如下:
  1. public HashMap(int initialCapacity, float loadFactor) {  
  2.     ...  
  3.     this.loadFactor = loadFactor;  
  4.     this.threshold = tableSizeFor(initialCapacity);  
  5. }  
  6.   
  7. public HashMap(int initialCapacity) {  
  8.     this(initialCapacity, DEFAULT_LOAD_FACTOR);  
  9. }  
  10.   
  11. public HashMap() {  
  12.     this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted  
  13. }  
  14.   
  15. public HashMap(Map<? extends K, ? extends V> m) {  
  16.     this.loadFactor = DEFAULT_LOAD_FACTOR;  
  17.     putMapEntries(m, false);  
  18. }  

其中主要有两种形式: 值得注意的是,当我们自定义HashMap初始容量大小时,构造函数并非直接把我们定义的数值当做HashMap容量大小,而是把该数值当做参数调用方法tableSizeFor,然后把返回值作为HashMap的初始容量大小:
  1. /** 
  2.  * Returns a power of two size for the given target capacity. 
  3.  */  
  4. static final int tableSizeFor(int cap) {  
  5.     int n = cap - 1;  
  6.     n |= n >>> 1;  
  7.     n |= n >>> 2;  
  8.     n |= n >>> 4;  
  9.     n |= n >>> 8;  
  10.     n |= n >>> 16;  
  11.     return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;  
  12. }  

该方法会返回一个大于等于当前参数的2的倍数,因此HashMap中的table数组的容量大小总是2的倍数。

标签:扩容,HashMap,容量,ArrayList,元素,数组,loadFactor
来源: https://www.cnblogs.com/menghuantiancheng/p/10462376.html