ArrayList的数据结构java
ArrayList是一种线性数据结构,底层是动态数组实现的,与java中的数组相比,它的容量能够动态添加。数组
ArrayList的类结构数据结构
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ ...... }
ArrayList的主要成员变量dom
//默认容量 private static final int DEFAULT_CAPACITY = 10; private static final Object[] EMPTY_ELEMENTDATA = {}; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //ArrayList存储数据的数组 transient Object[] elementData; //存储元素数目 private int size; //默认最大容量数目 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // protected transient int modCount = 0;
ArrayList的构造方法this
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 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); } }
ArrayList的主要方法code
存:ci
boolean add(E e);element
public boolean add(E e) { //根据当前下角标size+1和当前数组的容量,判断是否须要扩容,若是须要,扩容到1.5倍 ensureCapacityInternal(size + 1); // Increments modCount!! //将新元素加入数组中,下角标为size+1 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //若是存储元素的数组为空,容量值为10和minCapacity中的较大者 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { //更新次数加一 modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) //若是minCapacity大于当前数组的长度,扩容 grow(minCapacity); } private void grow(int minCapacity) { //将当前数组的长度赋值给oldCapacity int oldCapacity = elementData.length; //新的容量值为原来的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) //若是新容量值比minCapacity 值小,新容量值即为minCapacity newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) //若是新容量值大于容许的最大长度 newCapacity = hugeCapacity(minCapacity); //根据容量建立一个新数组,并将旧数组的元素复制给新数组 elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow //若是minCapacity小于零,直接抛出OOM异常 throw new OutOfMemoryError(); //若是minCapacity大于最大数组容量,则返回Integer的最大值,不然返回 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
void add(int index,E e);rem
public void add(int index, E element) { //校验下角标index是否越界 rangeCheckForAdd(index); //判断是否须要扩容 ensureCapacityInternal(size + 1); // Increments modCount!! //将当前数组中下角标为[index,size]的元素复制到[index+1,size+1]的位置 System.arraycopy(elementData, index, elementData, index + 1, size - index); //将element放置到数组下角标为index的位置 elementData[index] = element; //数组内元素个数加1 size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) //若是index大于数组元素的个数,或者index<0,抛出下角标越界异常 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
E set(int index,E e);get
public E set(int index, E element) { //校验下角标是否越界 rangeCheck(index); //将数组中下角标为index的元素赋值给oldValue E oldValue = elementData(index); //再将新元素放置到下角标index位置 elementData[index] = element; //返回旧值 return oldValue; }
取:
E get(int index);
public E get(int index) { //校验下角标是否越界 rangeCheck(index); //返回数组中下角标为index的元素 return elementData(index); } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
移除:
E remove(int index);经过下角标移除。
public E remove(int index) { //判断下角标是否越界 rangeCheck(index); //修改次数加一 modCount++; //将数组中下角标为index的元素赋值给oldValue E oldValue = elementData(index); //要移动的元素个数 int numMoved = size - index - 1; if (numMoved > 0) //若是要移动的元素个数大于0,移动 // 将elementData数组index+1位置开始拷贝到elementData从index开始的空间 System.arraycopy(elementData, index+1, elementData, index, numMoved); //最后一个元素设为null,并将size-1 elementData[--size] = null; // clear to let GC do its work 返回旧值 return oldValue; }
boolean remove(Object o);移除指定元素
public boolean remove(Object o) { if (o == null) { //若是要移除的元素为null //循环遍历数组 for (int index = 0; index < size; index++) if (elementData[index] == null) { //若是某个下角标的元素为null //移除该下角标的元素 fastRemove(index); return true; } } else { //循环遍历数组 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { //若是某个下角标的元素为o ////移除该下角标的元素 fastRemove(index); return true; } } return false; } private void fastRemove(int index) { //修改次数加一 modCount++; //要移动的元素个数 int numMoved = size - index - 1; if (numMoved > 0) // 将elementData数组index+1位置开始拷贝到elementData从index开始的空间 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }