博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ArrayList和Vector的扩容机制
阅读量:4042 次
发布时间:2019-05-24

本文共 2416 字,大约阅读时间需要 8 分钟。

ArrayList中ensureCapacity扩容,trimToSize容量调整到适中,Vector的扩容,是可以指定扩容因子,同时Vector扩容策略是:原来容量的2倍与原来容量+扩容因子,两者中取容量大的,进行扩容

ArrayList和Vector都是继承了相同的父类和实现了相同的接口。如下 

Java代码  
  1. public class Vector<E>  
  2.     extends AbstractList<E>  
  3.     implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
  4. {}  
  5.   
  6. public class ArrayList<E> extends AbstractList<E>  
  7.         implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
  8. {}  

两者之间我认为主要有两个却别。 

1、Vector中的public方法都添加了synchronized关键字,以确保方法同步。 

2、内部属性不同,这也是导致扩容方式不同的原因所在。 


我现在来说第二条, 

ArrayList有两个属性,存储数据的数组elementData,和存储记录数目的size。 
Vector有三个属性,存储数据的数组elementData,存储记录数目的elementCount,还有扩展数组大小的扩展因子capacityIncrement。 


先来看ArrayList的扩展方法 

Java代码  
  1. public void ensureCapacity(int minCapacity) {  
  2. modCount++;//父类中的属性,记录集合变化次数  
  3. int oldCapacity = elementData.length;  
  4. if (minCapacity > oldCapacity) {  
  5.     Object oldData[] = elementData;  
  6.     int newCapacity = (oldCapacity * 3)/2 + 1;  
  7.         if (newCapacity < minCapacity)  
  8.     newCapacity = minCapacity;  
  9.     elementData = (E[])new Object[newCapacity];  
  10.     System.arraycopy(oldData, 0, elementData, 0, size);  
  11. }  
  12.    }  

重构下看起来更方便 

Java代码  
  1. public void ensureCapacity(int minCapacity) {  
  2. modCount++;//父类中的属性,记录集合变化次数  
  3. int oldCapacity = elementData.length;  
  4. if (minCapacity > oldCapacity) {
    //扩容的条件,数组需要的长度要大于实际长度  
  5.     Object oldData[] = elementData;  
  6.     int newCapacity = ((oldCapacity * 3)/2 + 1)<minCapacity?minCapacity: ((oldCapacity * 3)/2 + 1);  
  7.        elementData = (E[])new Object[newCapacity];  
  8.     System.arraycopy(oldData, 0, elementData, 0, size);  
  9. }  
  10.    }  

可以看到,再满足扩容条件时,扩展后数组大小为((原数组长度*3)/2+1)与传递参数中较大者 


再看看Vector的扩容方法 

Java代码  
  1. public synchronized void ensureCapacity(int minCapacity) {  
  2.     modCount++;//父类中的属性,记录集合变化次数  
  3.     ensureCapacityHelper(minCapacity);  
  4.     }  
  5.  private void ensureCapacityHelper(int minCapacity) {  
  6.     int oldCapacity = elementData.length;  
  7.     if (minCapacity > oldCapacity) {
    //扩容的条件,数组需要的长度要大于实际长度  
  8.         Object[] oldData = elementData;  
  9.         int newCapacity = (capacityIncrement > 0) ?  
  10.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);  
  11.             if (newCapacity < minCapacity) {  
  12.         newCapacity = minCapacity;  
  13.         }  
  14.         elementData = new Object[newCapacity];  
  15.         System.arraycopy(oldData, 0, elementData, 0, elementCount);  
  16.     }  
  17.     }  

可以看到,相对于ArrayList的扩容方法,这个方法被一分为2,老实说我更喜欢这样,方法的职责更加明确。 



int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2); 


当扩容因子大于0时,新数组长度为原数组长度+扩容因子,否子新数组长度为原数组长度的2倍。 



   if (newCapacity < minCapacity) {newCapacity = minCapacity;} 


将上面生成的新数组长度与传递的参数要求长度作比较,较大者为最终的新长度。

转载地址:http://man-yutao.iteye.com/blog/1317446

你可能感兴趣的文章
linux安装usb wifi接收器
查看>>
补充自动屏蔽攻击ip
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>
让我做你的下一行Code
查看>>
浅析:setsockopt()改善程序的健壮性
查看>>
关于对象赋值及返回临时对象过程中的构造与析构
查看>>
VS 2005 CRT函数的安全性增强版本
查看>>
SQL 多表联合查询
查看>>
Visual Studio 2010:C++0x新特性
查看>>
drwtsn32.exe和adplus.vbs进行dump文件抓取
查看>>
cppcheck c++静态代码检查
查看>>
在C++中使用Lua
查看>>
一些socket的编程经验
查看>>
socket编程中select的使用
查看>>
关于AIS编码解码的两个小问题
查看>>
GitHub 万星推荐:黑客成长技术清单
查看>>
可以在线C++编译的工具站点
查看>>
关于无人驾驶的过去、现在以及未来,看这篇文章就够了!
查看>>
所谓的进步和提升,就是完成认知升级
查看>>