private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
具体流程是,检查index是否越界->扩容检查->将index之后的元素往后移->将 element 赋值到 index 位置->数组 size 加 1。
4 remove(int index)
1 2 3 4 5 6 7 8 9 10 11 12 13
public E remove(int index) { rangeCheck(index);
modCount++; E oldValue = elementData(index);
int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue;
原理和add(int index, E element)类似,核心都是通过System.arraycopynative方法实现。
5 get(int index)
1 2 3 4 5 6 7 8 9
public E get(int index) { rangeCheck(index);
return elementData(index); }
E elementData(int index) { return (E) elementData[index]; }
获取元素更简单,直接根据 index 返回数组对应位置的元素即可。
6 遍历
对于ArrayList的遍历方式主要有两种。
第一种:
1 2 3
for (int i=0;i<size;i++) { System.out.println(list.get(i)); }
第二种:
1 2 3
for (String s : list) { System.out.println(s); }
那么这两种方式有什么区别呢??
对于第二种方式是一种增强型的for循环,我们反编译一下代码。
1 2 3 4 5 6 7
ArrayList var0 = new ArrayList(); Iterator var1 = var0.iterator();
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;
Itr() {}
public boolean hasNext() { return cursor != size; }
@SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification();