ArrayList源码
继承AbstractList
实现List、RandomAccess、Cloneable、Serializable
AbstractList抽闲类中定义继承AbstractList的SubList内部类
List接口定义List集合的操作方法
RandomAccess实现此接口的类可以随机访问
Cloneable实现此接口的类可以进行拷贝操作
重点说明:
1、使用数组存储数据
2、默认初始化大小为10
3、使用System.arraycopy(Object src,int srcPos,Object dest, int destPos,int length)进行数组间的拷贝
4、ensureCapacity(int minCapacity)方法,用于确保集合容量:
如果实际elementData数组不为空,则[最小扩容量]设置为默认容量10,
如果传入的[最小容量]大于[最小扩容量],并且[最小容量]大于[当前容量],则
先获得[当前容量]oldCapacity,
再计算newCapacity大小=(oldCapacity+oldCapacity/2)
如果newCapacity-minCapacity<0,则设置elementData为minCapacity大小
如果newCapacity-[Integer.MAX_VALUE - 8]>0,则调用hugeCapacity方法进行扩容
如果实际elementData数组为空,否则[最小扩容量]设置为0(不需要放大)。
5、clone()方法:
ArrayList克隆方法,数组元素本身不会被复制,只拷贝了数组指针,克隆后的数组元素与原有数组元素相同
ArrayList list = new ArrayList<>(); list.add("1"); System.out.println("原数组"+JSONObject.toJSONString(list)); ArrayList listClone = (ArrayList) list.clone(); listClone.add("2"); System.out.println("克隆数组"+JSONObject.toJSONString(listClone)); System.out.println("原数组"+JSONObject.toJSONString(list));
输出结果:
原数组["1"]
克隆数组["1","2"]
原数组["1"]
代码翻译:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; 定义默认集合大小 private static final int DEFAULT_CAPACITY = 10; 定义的ArrayList大小为0时,elementData=EMPTY_ELEMENTDATA private static final Object[] EMPTY_ELEMENTDATA = {}; //定义ArrayList()时,elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 实际用于存储ArrayList数据 transient Object[] elementData; // non-private to simplify nested class access ArrayList大小,包含的元素数量 private int size; 根据initialCapacity构建数组大小 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); } } 构建空的数组 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 根据指定的集合构建为数组 public ArrayList(Collection<? extends E> c) { //将集合转为数组,实际调用Arrays.copyOf(elementData, size); 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 { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } 根据size大小整理ArrayList的大小 public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } } 如果需要的话,放大ArrayList集合的大小以确保数组保存元素 public void ensureCapacity(int minCapacity) { //如果实际elementData不为空,则minExpand设置为DEFAULT_CAPACITY默认大小,否则minExpand设置为0(不需要放大) 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; //如果传入的最小容量大于最小扩展容量时,调用ensureExplicitCapacity进行扩展数组大小 if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } //如果当前数组大小等于空时,最小扩展容量=(默认小于与最小容量的最大值) private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } //只有传入的最小容量减去数组当前容量时,调用grow扩展当前数组容量 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } //数组的最大容量 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //根据minCapacity扩展数组容量, //先获得当前数组容量oldCapacity, //在计算newCapacity大小=(oldCapacity+oldCapacity/2) //如果newCapacity-minCapacity<0,则设置elementData为minCapacity大小 //如果newCapacity-数组允许的最大值>0,则调用hugeCapacity方法进行扩容 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); } //如果最新容量小于0,报错内存溢出 //否则设置最小容量>MAX_ARRAY_SIZE,则数组大小设置为Integer最大值,否则设置为(Integer最大值-8) private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //返回ArrayList大小 public int size() { return size; } //根据size判空 public boolean isEmpty() { return size == 0; } //返回是否包含e对象 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; } //从大到小顺序判断对象o在数组的中位置 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; } //ArrayList克隆方法,元素本身不会被复制,只拷贝了指针,克隆后的数组与原有数组相同 public Object clone() { try { ArrayList<?> v = (ArrayList<?>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } } //返回数组 public Object[] toArray() { return Arrays.copyOf(elementData, size); } //返回数组 @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } //获得指定索引的数据 @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } //获得指定索引的数据结果 public E get(int index) { rangeCheck(index); return elementData(index); } //替换指定索引位置的值 public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; } //在最后添加对象 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments 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++; } //通过移位的方式在指定索引的位置删除对象 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; } //顺序遍历,如果存在o对象就删除 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 } //清空数组,大小size设置为0 public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } //把集合C增加到数组中 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } //在指定索引添加集合c public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; } //通过拷贝的方式删除索引开始于截止中间的数组 protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); // clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; } //检查索引是否越界 private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //添加或者删除时检查索引是否越界 private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * Constructs an IndexOutOfBoundsException detail message. * Of the many possible refactorings of the error handling code, * this "outlining" performs best with both server and client VMs. */ private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } //根据集合批量删除数据 public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); } //根据集合批量保留数组中的数据:保存数组中在c集合中存在的对象 public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); } private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } }
收藏文章数量从多到少与“把书读薄”是一个道理