ArrayList和Vector的扩容机制

转自:http://man-yutao.iteye.com/blog/1317446

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

Java代码  

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

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

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;}

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

时间: 2024-08-27 17:43:05

ArrayList和Vector的扩容机制的相关文章

ArrayList源码解析(二)自动扩容机制与add操作

目录 1.ArrayList的自动扩容机制 2.add操作 正文 本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的.数组的特性是大小固定,这个特性导致的后果之一就是,当ArrayList中成员个数超过capacity后,就需要重新分配一个大的数组,并将原来的成员拷贝到新的数组之中. add操作前都需要保证capacity足够,因此扩容机制和add放

ArrayList、Vector、HashMap、HashTable、HashSet的默认初始容量、加载因子、扩容增量

这里要讨论这些常用的默认初始容量和扩容的原因是: 当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低. 加载因子的系数小于等于1,意指  即当 元素个数 超过 容量长度*加载因子的系数 时,进行扩容. 另外,扩容也是有默认的倍数的,不同的容器扩容情况不同. List 元素是有序的.可重复 ArrayList.Vector默认初始容量为10 Vector:线程

【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制

一 先从 ArrayList 的构造函数说起ArrayList有三种方式来初始化,构造方法源码如下:/** 默认初始容量大小*/private static final int DEFAULT_CAPACITY = 10; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /*默认构造函数,使用初始容量10构造一个空列表(无参数构造)*/public ArrayList() {this.elementDat

ArrayList的扩容机制

ArrayList的扩容机制: 当向ArrayList中添加元素的时候,ArrayList的存储容量如果满足新元素的容量要求,则直接存储:ArrayList的存储容量如果不满足新元素的容量要求,ArrayList会增强自身的存储能力,以达到存储新元素的要求. 因为不同的JDK版本的扩容机制可能有差异,下面以JDK1.8为例说明一.构造方法 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.element

【数组】- ArrayList自动扩容机制

不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力,ArrayList会增强自身的存储能力,已达到存储新元素的要求 ArrayList:本质通过内部维护的数组对象进行数据存储 ①:分析ArrayList的add(E)方法 public boolean add(E e) { ensureCapacityInternal(size + 1); // In

ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量

这里要讨论这些常用的默认初始容量和扩容的原因是: 当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低. 加载因子的系数小于等于1,意指 即当 元素个数 超过 容量长度*加载因子的系数 时,进行扩容. 另外,扩容也是有默认的倍数的,不同的容器扩容情况不同. List 元素是有序的.可重复 ArrayList.Vector默认初始容量为10 Vector:线程安

Java常见集合的默认大小及扩容机制

在面试后台开发的过程中,集合是面试的热话题,不仅要知道各集合的区别用法,还要知道集合的扩容机制,今天我们就来谈下ArrayList 和 HashMap的默认大小以及扩容机制. 在 Java 7 中,查看源码可以知道:ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂,为什么呢???下文有解释).这就是 Java 7 中 ArrayList 和 HashMap  类 的代码片段: // from ArrayList.java JDK 1.7 pri

ArrayList和Vector的区别?HashMap和HashTable的区别?StringBuilder、StringBuffer和String的区别?

ArrayList和Vector的区别?从两个方面 1.同步性:ArrayList是线程不安全的,是非同步的:Vector是线程安全的,是同步的.(Java中线程的同步也就满足了安全性) 2.数值增长:ArrayList每次增长为原来的50%;Vector每次增长为原来的100%; (从内部实现机制来讲,ArrayList和Vector都是使用数组(Array)来控制集合中的对象,当向集合中添加对象时,如果内部数组长度不够用时,长度会自动增长.ArrayList会增长为原来的1.5倍,Vecto

List ArrayList LinkedList vector简介与区别

ArrayList,LinkedList,Vestor这三个类都实现了java.util.List接口,但它们有各自不同的特性,主要如下: ArrayList:底层用数组实现的List 特点:查询效率高,增删效率低 轻量级 线程不安全 LinkedList:底层用双向循环链表 实现的List 特点:查询效率低,增删效率高 Vector: 底层用数组实现List接口的另一个类 特点:重量级,占据更多的系统开销 线程安全 一.同步性 ArrayList,LinkedList是不同步的,而Vestor