接上文分析ArrayList核心方法
1.作为动态数组,扩容方法至关重要
a.确保最低容量的公共方法
public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
b.内部的确保容量方法
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
c.实际的确保容量方法,modCount++,
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
d.增加容量的方法
d1.普通方法
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//容量增加1.5倍 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); }
d2.大容量
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
2.依次看增删改查方法,增删改都是结构性修改
a. add
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!!//为了增加modCount elementData[size++] = e; return true; }
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++; }
b.remove
public E remove(int index) { rangeCheck(index);//检查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//最后一个元素设为null,同时减小size return oldValue; }
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++)//通过迭代的方式判断要删除的元素 if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
private void fastRemove(int index) { modCount++; 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 }
c.set
public E set(int index, E element) { rangeCheck(index);//检测index合法性 E oldValue = elementData(index);//取出现在的值 elementData[index] = element;//直接修改数组 return oldValue; }
E elementData(int index) { return (E) elementData[index]; }
d.get
public E get(int index) { rangeCheck(index);
//检测index合法性
return elementData(index)
;//直接取值}
e.contains,index,lastIndex
public boolean contains(Object o) { return indexOf(o) >= 0;//通过o的索引位置判断是否存在 }
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; }
public int lastIndexOf(Object o) {//倒序遍历数组 if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }
f.clear
public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }