Java集合框架:ArrayList扩容机制解释,arraylist扩容
分享于 点击 31246 次 点评:166
Java集合框架:ArrayList扩容机制解释,arraylist扩容
1、java中ArrayList该类的定义
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* 默认容量为10
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空数组:用于调用带有容量切容量为0时初始化elementData这个值
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 空数组:用于调用空构造时初始化elementData这个值
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
*数组变量
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* arrayList的长度
*/
private int size;
//后面自己需要看源码
...
}
2、ArrayList描述
ArrayList是一个继承abstractList和实现List的接口的实现类。 ArrayList是以数组实现的数组队列,允许重复。可以通过ArrayList来进行增加,删除,修改,遍历等操作。ArrayList可以说是一个动态数组。动态的最好例子可以说就是ArrayList的底层是数组,该数组的长度可以根据实际需要不断增加。
3、ArrayList的扩容机制
3.1 对外提供的检查是否需要扩容方法
public void ensureCapacity(int minCapacity) { //判断elementData是否是默认空数组,如果不是minExpand为0,如果是minExpand=DEFAULT_CAPACITY=10 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY; //如果我们预测的值比数组elementData数组的长度实际要大,需要扩容。只能说明我们需要更大容器的列表。 if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
3.2 内部实现的扩容机制
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//父类AbstractLisy生命的属性
// overflow-conscious code
if (minCapacity - elementData.length > 0)//我们需要的长度比elementData的长度大,扩容
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//获取当前存放数据数组的长度
int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容到原来数组长度的1.5倍
if (newCapacity - minCapacity < 0)//如果扩容到长度的1.5倍以后,仍然不够用,直接将我们预计的值作为扩容长度
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//扩容上限最大值为Integer的最大值-8,如果超过这个最大值,使用下面的方法
newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//使用数组Arrays的copyOf()进行扩容,每次扩容都采用System.arrayCopy()复制到新数组的
}
private static int hugeCapacity(int minCapacity) {//如果扩容超过Integer.MAX_VALUE-8,代码会走该方法
if (minCapacity < 0) // overflow throw new OutOfMemoryError();
//如果我们预测的长度比Integer.MAX_VALUE-8大,最后取Integer.MAX_VALUE。
return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
4、ArrayList遍历方式
List<String> testList = new ArrayList<String>();
testList.add("11");
testList.add("21");
testList.add("31");
testList.add("41");
testList.add("51");
testList.add("61");
testList.add("71");
/**
* for循环遍历
*/
for(int index=0;index<testList.size();index++){
System.out.println(testList.get(index));
}
System.err.println("===========foreach===========");
/**
* foreach遍历
*/
for(String index:testList){
System.out.println(index);
}
System.err.println("===========Iterator===========");
/**
* 迭代器Iterator
*/
Iterator<String> iterator = testList.iterator();
while(iterator.hasNext()){
System.err.println(iterator.next());
}
5、ArrayList和vector比较
普及:什么是线程安全什么是线程不安全
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 如图,List接口下面有两个实现,一个是ArrayList,另外一个是vector。 从源码的角度来看,因为Vector的方法前加了,synchronized 关键字,也就是同步的意思,sun公司希望Vector是线程安全的,而希望arraylist是高效的,缺点就是另外的优点。
1、Vector每次扩容都是请求其大小的2倍空间,而ArrayList是1.5倍
2、Vector还有一个子类Stack
相关文章
- 暂无相关文章
用户点评