ArrayList关键参数:
/** * 默认初始容量. */ private static final int DEFAULT_CAPACITY = 10; /** * 参数为0时使用该数组存储数据. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 构造为空时使用该数组存储数据,第一次add元素时默认容量为10. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * List所被修改次数 */ protected transient int modCount = 0;
init 初始化
/** * 使用空构造函数,初始化存储容器为DEFAULTCAPACITY_EMPTY_ELEMENTDATA. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 如果为0时,使用EMPTY_ELEMENTDATA 为存储容器,如果大于0,重新初始化一个指定大小的数组存 * 储容器,负数时抛出异常. */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * 将传过来的Collection实现类转为数组后,判断其大小是否为0,如果不为0时判断是否是Object[] * 类,如果不是则使用方法进行Arrays.copyOf(这是JDK的一个BUG,编号为6260652). * 如果为0则使用参数为0的构造参数. */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { this.elementData = EMPTY_ELEMENTDATA; } }
1、使用空构造函数,初始化存储容器为DEFAULTCAPACITY_EMPTY_ELEMENTDATA.
2、构造参数如果为0时,使用EMPTY_ELEMENTDATA 为存储容器,如果大于0,重新初始化一个指定大小的数组存储容器,负数时抛出异常.
3、将传过来的Collection实现类转为数组后,判断其大小是否为0,如果不为0时判断是否是Object[] 类,如果不是则使用方法进行Arrays.copyOf(这是JDK的一个BUG,编号为6260652). 如果为0则使用参数为0的构造参数.
add 数据添加
/** * 添加元素. */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** * Inserts the specified element at the specified position in this * list. Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). * * @param index index at which the specified element is to be inserted * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } /** * 修改次数++, * 如果增加数据后容量大于当前存储容器容量,则进行扩容. */ private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } /** * 容量扩容为当前的1.5倍 (oldCapacity >> 1(一半)) */ 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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
1、第一次添加元素时,如果数组为默认存储容器,则扩容存储容器大小为10。超过容量时扩容为原来的1.5倍.
int newCapacity = oldCapacity + (oldCapacity >> 1)
2、如果不为默认存储容器,则默认大小为1,每次超过容量扩容为原来的1.5倍.
contains 判断是否包含某元素
public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { 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; } return -1; }
1、调用 indexOf 判断坐标是否为负数,坐标大于0则表示存在。
remove 移除元素
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; }
1、要迁移的值的个数 numMoved,从后边数numMoved 个数的元素全部向前移动一位,将最后以为置空。