ArrayList、HashMap扩容

1.ArrayList扩容

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


2.HashMap扩容

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

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

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

HashMap中的变量

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

 

  • Node<K,V>:链表节点,包含了key、value、hash、next指针四个元素
  • table:Node<K,V>类型的数组,里面的元素是链表,用于存放HashMap元素的实体
  • size:记录了放入HashMap的元素个数
  • loadFactor:负载因子
  • threshold:阈值,决定了HashMap何时扩容,以及扩容后的大小,一般等于table大小乘以loadFactor

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的形式,在此不作讨论
  • 定义初始容量大小(table数组的大小,缺省值为16),定义负载因子(缺省值为0.75)的形式
值得注意的是,当我们自定义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的倍数。

posted on 2019-03-02 18:40  温故而知新,少年  阅读(1738)  评论(0编辑  收藏  举报

导航