ArrayList简介
ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小。要注意的是ArrayList并不是线程安全的,因此一般建议在单线程中使用ArrayList。
ArrayList的继承关系
1
2
3public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
由上可知ArrayList继承AbstractList 并且实现了List和RandomAccess,Cloneable, Serializable接口。
ArrayList的方法使用和源码解析
①构造方法
1 | //1----------------------- |
由上面三种构造方法可知,默认情况下使用ArrayList会生成一个大小为10的Object类型的数组。也可以调用ArrayList(int initialCapacity)
来初始化Object数组的大小。并且用户可以往ArrayList中传入一个容器只要这个容器是Collection类型的。调用ArrayList(Collection<? extends E> c)
接口的时候会将容器数组化处理并将这个数组值赋给Object数组。
实例:
1 | public static void main(String[] args) { |
②indexOf(Object o)方法
功能:查找某个元素在ArrayList中第一次出现的位置。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public int indexOf(Object o) {
//ArrayList中的元素可以为null,如果为null返回null的下标
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
//如果没有找到对应的元素返回-1。
return -1;
}
对于indexof方法做几点说明:ArrayList中可以存放null元素,indexof是返回elementData数组中值相同的首个元素的下标,indexof中比较方法是equals而equals是比较元素的值,因此必须对null单独查找。如果未找到该元素则返回-1 。
1 |
|
③lastIndexOf(Object o)方法
功能:查找某个元素在ArrayList中最后出现的位置。1
2
3
4
5
6
7
8
9
10
11
12
13
14public int lastIndexOf(Object o) {
if (o == null) {
//如果o为null从后往前找到第一个为null的下标
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
//从后往前找到第一个值为o的下标
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
上面代码做几点说明:lastIndexOf(Object o)在ArrayList中从后往前找到第一个跟要查找值相同的元素的下标,因为是按值查找所以对于 null 要单独查找。如果未找到则返回-1;
④get(int index)方法
功能:返回ArrayList中指定下标为index的元素。
1 | public E get(int index) { |
对上面代码做几点说明:上面代码中只检查了index>=size的情况,在index<0的情况下也会抛出异常,只是这个异常是由系统抛出的。index>=size要检查的原因是有可能数组的大小大于index,然而有效里面的元素<index
这时不抛异常就会返回无效值。举个例子ArrayList的初始化大小为10,现在往里面放5个元素,如果index>=5时,应该要抛出异常,而不是返回 null。因为null 是可以主动放在ArrayList中的。0的情况下也会抛出异常,只是这个异常是由系统抛出的。index>
⑤set(int index, E element)方法
功能:将element放到ArrayList下标为index的位置,如果index<0或index>=size 抛异常,set(int index, E element)只能覆盖ArrayList中原来的元素,返回值为被覆盖的元素。0或index>
1 | //1 |
⑥add(E e)方法
功能:往ArrayList中添加元素。
1 | //1----------------------- |
add方法比较复杂,涉及到扩充数组容量的问题。其中要弄清楚size和elementData.length的区别,size指的是数组中存放元素的个数,elementData.length表示数组的长度,当new一个ArrayList系统默认产生一个长度为10的elementData数组,elementData.length=10,但是由于elementData中还未放任何元素所有size=0。如果加入元素后数组大小不够会先进行扩容,每次扩容都将数组大小增大一半比如数组大小为10一次扩容后的大小为10+5=10;ArrayList的最大长度为 2^32 .
⑦add(int index, E element)方法
功能:往ArrayList指定index上添加元素,添加元素后ArrayList的大小增1。index及以后的元素都会向后移一位。
1 | //1------------------------- |
add(int index, E element)往指定index中加入元素,加入元素之前先检查数组的大小,如果小了在原来基础上增大一半,将ArrayList只能怪index及以后的元素往后移一位,将element放到index位置。
⑧remove(int index)方法
功能:删除ArrayList指定位置的元素。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public E remove(int index) {
rangeCheck(index);
//如果index>=size抛出异常
modCount++;
E oldValue = elementData(index);
//获取删除元素的值
int numMoved = size - index - 1;
//将index后面所有的元素往前移一位。
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
//返回要删除的原数。
return oldValue;
}
⑨remove(Object o)方法
功能:删除ArrayList中值为o的元素
1 | public boolean remove(Object o) { |