JAVA系列集合之-ArrayList
1. ArrayList 简介
- ArrayList 是个数组,但是可自动扩容的动态数组。和普通的数组相比,它的容量能够动态的增长,默认大小为10,每次插入数据的时候都会比较插入数据后和数组长度的大小,如果数组长度小则扩容0.5倍。
- ArrayList继承了AbstractList、实现了List、RandomAccess、Cloneable、Serializable接口
- 继承了List的接口并且实现了AbstractList,ArrayList就有了增、删、改、查、判空、迭代器等功能
- 实现了RandomAccess接口则能够实现快速访问(RandomAccess基础的接口没有任何方法的时间,就是标记实现类是否具备快速访问的特性)
- 实现了Cloneable接口则说明ArrayList支持Object的clone的方法,如果不继承调用clone方法会抛出CloneNotSupportedException的错误,看了下源码,是native方法实现的
- 实现了Serializable接口则说明ArrayList能够被序列化和反序列化,能够在网络中进行传输
- 从ArrayList的源码中可以看到,没有任何锁的添加,所以ArrayList是非线程安全的,对应的线程安全的实现类是Vector,此种类型的数据会在接下来的文章有有所介绍。
2.Arraylist的数据结构
ArrayList的继承关系:
java.lang.Object ↳ java.util.AbstractCollection<E> ↳ java.util.AbstractList<E> ↳ java.util.ArrayList<E> public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
ArrayList与Collection的关系如下图:(此图来源于网络)
ArrayList两个属性是最重要的
- elementData:本质是Object[]数组,在默认的构造器中,会将初始化的值设置为10,同时也提供了构造器去初始化容量的大小,但它是个动态数组,elementData数组的大小会根据ArrayList的容量的增长而动态的增长。
- size:动态数组的实际大小
3.ArrayList的集中遍历方式
ArrayList支持3种遍历方式:
- 第一种:通过随机访问读取
ArrayList<Integer> list = new ArrayList();
Integer value = null; int size = list.size(); for (int i=0; i<size; i++) { value = (Integer)list.get(i); }
- 第二种:通过for循环遍历(进行文件编译后实质也是迭代器的实现)
ArrayList<Integer> list = new ArrayList();
Integer value = null;
for (Integer integ:list) {
value = integ;
}
- 第三种:通过迭代器进行遍历,即 Iterator去遍历
ArrayList<Integer> list = new ArrayList();
Integer value = null; Iterator iter = list.iterator(); while (iter.hasNext()) { value = (Integer)iter.next(); }
4.ArrayList的总结
- ArrayList实际上是用数组去保存数据,数组的默认长度是10,数组数据的插入,内部的动态数据会扩容
- 扩容机制:newCapacity = oldCapacity/2 + 1
- ArrayList实现Serializable,当写入到输出时候,先写入容量,在一次写入每一个数据,当读取输入的时候,先读取容量,在一次读取每一个数据