一、简介:
讲解的版本是JDK 1.8。ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。
二、重要成员变量:
transient Object[] elementData:保存元素
private int size:当前保存的元素数量
private static final int DEFAULT_CAPACITY = 10:默认数组大小
三、构造方法:
arrayList有三个构造方法,看下最只要的:
1 public ArrayList(int initialCapacity) { 2 if (initialCapacity > 0) { 3 this.elementData = new Object[initialCapacity]; 4 } else if (initialCapacity == 0) { 5 this.elementData = EMPTY_ELEMENTDATA; 6 } else { 7 throw new IllegalArgumentException("Illegal Capacity: "+ 8 initialCapacity); 9 } 10 }
initialCapacity为传入的初始容量,如果大于0,则创建数组,否则,使用默认大小为0的数组;
四、重要的方法:
1.add():
1 public boolean add(E e) { 2 //检查是否越界 3 ensureCapacityInternal(size + 1); // Increments modCount!! 4 //插入元素 5 elementData[size++] = e; 6 return true; 7 } 8 9 private void ensureCapacityInternal(int minCapacity) { 10 //如果是开始起始时的空数组,则在默认容量和minCapacity中选择较大的 11 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 12 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); 13 } 14 15 ensureExplicitCapacity(minCapacity); 16 } 17 private void ensureExplicitCapacity(int minCapacity) { 18 modCount++; 19 20 // overflow-conscious code 21 //如果当前需要的大小大于数组总容量,则对数组扩容 22 if (minCapacity - elementData.length > 0) 23 grow(minCapacity); 24 } 25 26 private void grow(int minCapacity) { 27 // overflow-conscious code 28 int oldCapacity = elementData.length; 29 //计算新容量 30 int newCapacity = oldCapacity + (oldCapacity >> 1); 31 //如果新容量还是小于需要的大小,则使用需要的大小作为新容量 32 if (newCapacity - minCapacity < 0) 33 newCapacity = minCapacity; 34 if (newCapacity - MAX_ARRAY_SIZE > 0) 35 newCapacity = hugeCapacity(minCapacity); 36 // minCapacity is usually close to size, so this is a win: 37 //将原数组拷贝到创建的数组中然后赋值给elementData,最终调用System.arraycopy()来完成 38 elementData = Arrays.copyOf(elementData, newCapacity); 39 }
代码关键部分都做了注释,就不在解释了。
2.get():
1 public E get(int index) { 2 //检查索引是否越界 3 rangeCheck(index); 4 //直接返回元素 5 return elementData(index); 6 } 7 private void rangeCheck(int index) { 8 if (index >= size) 9 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 10 }
3.remove(int index):
1 public E remove(int index) { 2 //检查数组是否越界 3 rangeCheck(index); 4 5 modCount++; 6 获取要删除的元素 7 E oldValue = elementData(index); 8 //计算要移动的元素数量 9 int numMoved = size - index - 1; 10 if (numMoved > 0) 11 //将被删除元素后面的所有元素向前移动一个位置 12 System.arraycopy(elementData, index+1, elementData, index, 13 numMoved); 14 elementData[--size] = null; // clear to let GC do its work 15 //返回被删除的元素 16 return oldValue; 17 }
这样基本的操作就讲完了,还是挺简单的吧。