一、ArrayList概述
实现了List接口的可扩容数组,实现了所有可选列表操作,如添加元素,包含元素等。
从jdk1.2开始有的,学习可以参考 Collection、List、LinkedList、Vector(向量)
注意:ArrayList和Vector功能一模一样,底层都是基于动态数组实现的
区别: ArrayList是非线程安全的容器
Vector是线程安全的容器,操作方法都加了同步锁
二、 ArrayList属性
1. private static final long serialVersionUID = 8683452581122892189L;
是因为实现了Serializable接口,是序列号
2. private static final int DEFAULT_CAPACITY = 10;
ArrayList根据调用不同的构造函数,初始化容量不同
Vector默认的容量是10
3. private static final Object[] EMPTY_ELEMENTDATA = {};
4. private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
三、 ArrayList构造方法
1. 无参构造
默认容量是0
2. 有参构造
除负数外,传递为多少,默认就是多。
传入一个初始化容量,
若初始化容量 > 0,用传入的值
若初始化容量 = 0,空(还是相当于用传入的值)
若初始化容量 < 0,抛出异常
3. 有参构造
容量总结:
ArrayList根据调用不同的构造函数,初始化容器不同
1). 如果使用无参的构造,默认容量是0,节约内存。 一旦添加元素,会发生第一次扩容, 默认容量为10(后面的add方法会提到);
2). 如果有参的构造,则传递为多少,默认就是多少。
ArrayList alist = new ArrayList(); // 默认容量0
ArrayList alist = new ArrayList(8); // 默认容量8
注意: 如果在开发过程中,数据大小基本确定,建议使用有参的构造函数,减少频繁扩容,提高 性能(如存12个数,用有参构造直接一次性扩容好了;用无参构造,传第一个值触发一 次扩容,扩容到10,传第十一个值的时候再次引发扩容)
当然如果不能确定的话,可以使用无参的构造。
具体问题具体分析
四、 ArrayList普通方法
1. 添加 add(){}方法
1). public boolean add(E e) {}
把一个值添加到数组中。
如果满了,进行扩容操作
添加元素,size加1
oldCapacity = 原有数组长度
如果oldCapacity > 0,或者elementData不为空,进入newLength函数。prefLength = 原数组 +
[原数组长 - (数组长度 + 1)] 和 原数组长度1.5倍的最大值。如果prefLength在0到int类型最大值-8之间(正常情况),将其返回,prefLength值作为新数组长度;如果prefLength的值非常大,则进入hugeLength,minLength = 原有数组长度 + [原数组长 - (数组长度 + 1)],如果这个数 < 0 ,即值太大,超出int的存储范围,则抛出OutOfMemoryError异常(内存耗尽);如果<=Integer.MAX_VALUE - 8,则返回Integer.MAX_VALUE - 8;否则返回minLength。将各自返回的值作为新数组长度
如果是其他情况,如第一次扩容,则返回默认容量10 和 长度+1的最大值,创建最大值的数组长度
2). public void add(int index, E element) {}
根据索引添加元素。
首先根据索引找到位置,先判断索引下标存在,不存在抛出下标越界。
之后看是否达到容量,若达到进行扩容。进行拷贝,之后继续添加
2. 删除remove(){}方法
1). public boolean remove(Object o) {}
先遍历查找,分别查找要删除的是null 或 正常值的下标位置,如果未找到,返回false,如果找到了,传入fastRemove(){}方法,如果要删除的元素不是最后一个,从i + 1位置的元素到最后一个元素拷贝到i位置到倒数第二个位置;如果要删除的元素是最后一个,置空
2). public E remove(int index) {}
根据下标删除元素
先用checkIndex()方法判断索引位置的合法性,如果索引 < 0,或索引 >= length ,抛出异常;如果没有异常,一直向上进行返回,继续remove中的代码,调用fastRemove(){}方法,和remove(Object o)中的一样,最后返回删除的这个值
3. 修改方法
public E set(int index, E element) {}
根据下标获得值,先利用checkIndex()方法判断索引的合法性,同remove(int index)方法,若下标存在,先存储旧值,之后修改该索引的元素值为新值,最后返回旧值
4. 查询方法
public E get(int index) {}
根据下标获得值,先利用checkIndex()方法判断索引的合法性,同remove(int index)方法,若下标存在,则返回对应下标的元素值
5. 包含方法
public boolean contains(Object o) {}
遍历,找到为空 或 其他情况的下标,若找到,则返回下标;若找不到,则返回-1 。最后返回 返回值是否 >= 0(若是,则return true,包含;若不是,则return false,不包含)