Java基础之Collections框架List接口实现类ArrayList及其源码分析

    技术2022-07-12  73

    Java基础之Collections框架List接口实现类ArrayList及其源码分析

    ArrayList的简单使用ArrayList源码分析 List接口的可调整大小的数组实现。 实现所有可选的列表操作,并允许所有元素,包括null。 除了实现List接口之外,此类还提供一些方法来操纵内部用于存储列表的数组的大小。 size,isEmpty,get,set,iterator和listIterator操作在恒定时间内运行。 加法运算以固定的固定时间运行,即,添加n个元素需要O(n)时间。 所有其他操作均以线性时间运行. 每个ArrayList实例都有一个容量。 容量是用于在列表中存储元素的数组的大小。 它总是至少与列表大小一样大。 将元素添加到ArrayList时,其容量会自动增长。 应用程序可以使用ensuresureCapacity操作在添加大量元素之前增加ArrayList实例的容量。 这可以减少增量重新分配的数量。

    ArrayList的简单使用

    List<String> list = new ArrayList<String>(); //新增元素 list.add("tony"); list.add("projects"); System.out.println(list.toString()); //移除指定元素 list.remove("projects"); System.out.println(list.toString()); Set<String> setTemp = new HashSet<String>(); setTemp.add("projects"); setTemp.add("tony"); //添加置顶集合中的所有元素 list.addAll(setTemp); System.out.println(list.toString()); //获取指定元素的索引 System.out.println(list.indexOf("tony")); //获取指定元素最后一次的索引 System.out.println(list.lastIndexOf("tony")); //判断是否包含指定元素 System.out.println(list.contains("tony")); //获取指定索引下的元素 System.out.println(list.get(0)); //进行排序 Collections.sort(list);; System.out.println(list.toString()); ......

    ArrayList源码分析

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { //序列化值 private static final long serialVersionUID = 8683452581122892189L; /** * 默认的容量大小为10 */ private static final int DEFAULT_CAPACITY = 10; /** * 用于空实例的共享空数组实例. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** 共享的空数组实例,用于默认大小的空实例。 我们将此与EMPTY_ELEMENTDATA区别开来,知道何时需要扩充容量进行添加第一个元素 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * 存储ArrayList元素的数组缓冲区 * ArrayList的容量是此数组缓冲区的长度.任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList * 添加第一个元素时,将扩展为DEFAULT_CAPACITY */ transient Object[] elementData; //非私有以简化嵌套类访问 /** ArrayList的大小 */ private int size; /** * 构造一个具有指定初始容量的空列表. */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { //大于0就创建一个默认的容量列表 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { //等于0的时候创建一个空的列表 this.elementData = EMPTY_ELEMENTDATA; } else { //容量小于0的情况将抛出异常 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * 构造一个初始容量为10的空列表 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** 构造一个包含指定元素的列表集合,按集合的返回顺序迭代器。 */ 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) //进行数组的copy elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // 集合为空就创建一个空的数组 this.elementData = EMPTY_ELEMENTDATA; } } /** 将该ArrayList实例的容量修改为列表的当前大小。 应用程序可以使用此操作来最小化ArrayList 实例的存储。 */ public void trimToSize() { modCount++; //元素个数小于数组的大小,说明可以调整 if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } } /** 增加此ArrayList 实例的容量,如果必要,以确保它至少可以容纳数量的元素由最小容量参数指定。 */ public void ensureCapacity(int minCapacity) { //如果不是空的数组 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // 任何大小(如果不是默认元素表) ? 0 // 大于默认值的默认空表。 它应该已经是默认大小。 : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } //确保容量 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; if (minCapacity - elementData.length > 0) grow(minCapacity); } /** * 要分配的最大数组大小 * 一些虚拟机在数组中保留一些标题字 尝试分配更大的数组可能会导致OutOfMemoryError:请求的数组大小超出了VM限制 */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** 增加容量以确保它至少可以容纳最小容量参数指定的元素数。 */ private void grow(int minCapacity) { int oldCapacity = elementData.length; //等于原来元素组的大小 + 原来元素组的大小 / 2 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity通常接近大小,进行数据copy操作 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; } /** * 返回列表中元素的数量 */ public int size() { return size; } /** 返回list是否为空 */ public boolean isEmpty() { return size == 0; } /** 返回数组中是否包含指定元素 */ 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 } /** 返回指定元素最后一次出现的索引 */ 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; //如果不存在就返回-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) { throw new InternalError(e); } } /** 返回一个包含此列表中所有元素的数按正确的顺序 */ public Object[] toArray() { return Arrays.copyOf(elementData, size); } /** 返回指定类型的数组 */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // 创建一个新的a的运行时类型数组 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); // 增加modCount elementData[size++] = e; return true; } /** 将指定的元素插入此位置中的指定位置清单。 移动当前在该位置的元素(如果有),然后右边的任何后续元素(将其索引加一个)。 */ public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); 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; // 这是为null,让GC回收 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; //如果不存在就返回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; // 这是为null,让GC回收 } /** 移除列表中的所有元素 */ public void clear() { modCount++; // 这是为null,让GC回收 for (int i = 0; i < size; i++) elementData[i] = null; //将所有元素设置为null size = 0; } /** 将指定集合中的所有元素追加到此列表,由它们按顺序返回指定集合的​​Iterator */ public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; //进行数组扩容 ensureCapacityInternal(size + numNew); System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } /** 将指定集合中的所有元素插入此对象列表,从指定位置开始 */ public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; //进行数组扩容 ensureCapacityInternal(size + numNew); 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; } /** 从该列表中删除索引在之间的所有元素 fromIndex(含)和toIndex(不含) */ protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); 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)); } /** * add和addAll使用的rangeCheck版本 */ private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** 构造一个IndexOutOfBoundsException详细消息 */ private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } /** 从此列表中删除包含在其中的所有元素指定的集合。 */ public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); } /** 仅保留此列表中包含在指定的集合 */ public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); } /** 批量移除元素,complement是否保留指定列表的元素删除其他的 */ 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 { // 保留与AbstractCollection的行为兼容性 if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // 这是为null,让GC回收 for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } /** 序列化list列表 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // 写出元素计数以及任何隐藏的内容 int expectedModCount = modCount; s.defaultWriteObject(); // 写出大小作为与clone()行为兼容的容量 s.writeInt(size); //按照正确的顺序写出所有元素。 for (int i=0; i<size; i++) { s.writeObject(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } /** 反序列化 */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { elementData = EMPTY_ELEMENTDATA; //设置一个空的数组 // 读取大小和任何隐藏的东西 s.defaultReadObject(); // 读取容量 s.readInt(); // ignored if (size > 0) { // 像clone()一样,根据大小而不是容量分配数组 ensureCapacityInternal(size); Object[] a = elementData; // 按适当的顺序读取所有元素 for (int i=0; i<size; i++) { a[i] = s.readObject(); } } } /** 返回此列表中元素的列表迭代器(正确序列),从列表中的指定位置开始。 */ public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } /** 返回此列表中元素的列表迭代器(正确序列)。 */ public ListIterator<E> listIterator() { return new ListItr(0); } /** * 以适当的顺序返回此列表中元素的迭代器 */ public Iterator<E> iterator() { return new Itr(); } /** * 返回一个迭代器,优化之后的版本 */ private class Itr implements Iterator<E> { int cursor; // 下一个要返回的元素的索引 int lastRet = -1; // 最后返回元素的索引;如果没有 为-1 int expectedModCount = modCount; //返回是是否有写一个元素,如果下一个的索引等于数组的大小值,则返回false public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { //检查expectedModCount 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]; } //进行remove的时候需要调用next,不然会抛出异常,由上面的方法可以给lastRet进行赋值 public void remove() { if (lastRet < 0) throw new IllegalStateException(); //检查expectedModCount checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //进行for流的遍历Consumer<? super E> consumer @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // 在迭代结束时更新一次,以减少堆写入流量 cursor = i; lastRet = i - 1; checkForComodification(); } //检查expectedModCount final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } //判断是否有上一个元素 public boolean hasPrevious() { return cursor != 0; } //获取下一个的索引 public int nextIndex() { return cursor; } //获取前一个索引 public int previousIndex() { return cursor - 1; } //获取当前索引的上一个元素 @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[lastRet = i]; } //替换指定索引位置的值为e public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //添加一个元素(当前元素下标之后) public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } } /** * 返回指定位置之间此列表部分的视图fromIndex(含)和toIndex(不含) */ public List<E> subList(int fromIndex, int toIndex) { //检查相关索引的合法性 subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); } static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } @Override public void forEach(Consumer<? super E> action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @SuppressWarnings("unchecked") final E[] elementData = (E[]) this.elementData; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { action.accept(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } /** 返回Spliterator */ @Override public Spliterator<E> spliterator() { return new ArrayListSpliterator<>(this, 0, -1, 0); } /**基于索引的二分之一,延迟初始化的Spliterator */ static final class ArrayListSpliterator<E> implements Spliterator<E> { /* * 如果ArrayList是不可变的,或结构上不可变的 我们可以实现他们的分离器与Arrays.spliterator。相反,我们检测到遍历过程中的干扰牺牲很多性能. 我们主要依靠modCounts。 */ private final ArrayList<E> list; private int index; // 当前索引,在提前/拆分时修改 private int fence; //-1,直到使用; 然后是最后一个索引 private int expectedModCount; //设置fence时初始化 /** 创建覆盖给定范围的新分离器 */ ArrayListSpliterator(ArrayList<E> list, int origin, int fence, int expectedModCount) { this.list = list; this.index = origin; this.fence = fence; this.expectedModCount = expectedModCount; } private int getFence() { // 初始化 fence int hi; //一个专门的变体出现在forEach方法中 ArrayList<E> lst; if ((hi = fence) < 0) { if ((lst = list) == null) hi = fence = 0; else { expectedModCount = lst.modCount; hi = fence = lst.size; } } return hi; } public ArrayListSpliterator<E> trySplit() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; return (lo >= mid) ? null : // 除非太小,否则将范围分成两半 new ArrayListSpliterator<E>(list, lo, index = mid, expectedModCount); } public boolean tryAdvance(Consumer<? super E> action) { if (action == null) throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } return false; } public void forEachRemaining(Consumer<? super E> action) { int i, hi, mc; // hoist accesses and checks from loop ArrayList<E> lst; Object[] a; if (action == null) throw new NullPointerException(); if ((lst = list) != null && (a = lst.elementData) != null) { if ((hi = fence) < 0) { mc = lst.modCount; hi = lst.size; } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i]; action.accept(e); } if (lst.modCount == mc) return; } } throw new ConcurrentModificationException(); } //返回预估值 public long estimateSize() { return (long) (getFence() - index); } public int characteristics() { return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; } } @Override public boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); // 找出要删除的元素在此阶段从筛选谓词引发的任何异常将使集合保持不变 int removeCount = 0; final BitSet removeSet = new BitSet(size); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { @SuppressWarnings("unchecked") final E element = (E) elementData[i]; if (filter.test(element)) { removeSet.set(i); removeCount++; } } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } // 将剩余的剩余元素移到已删除元素剩余的空间上 final boolean anyToRemove = removeCount > 0; if (anyToRemove) { final int newSize = size - removeCount; for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) { i = removeSet.nextClearBit(i); elementData[j] = elementData[i]; } for (int k=newSize; k < size; k++) { elementData[k] = null; } this.size = newSize; if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } return anyToRemove; } //替换所有元素,接受一个函数式接口 //UnaryOperator表示对单个操作数产生的运算结果与操作数相同的类型。 这是{@code Function}的专门用于操作数和结果为相同类型的情况。 @Override @SuppressWarnings("unchecked") public void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { elementData[i] = operator.apply((E) elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } //进行排序指定比较器 @Override @SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); //expectedModCount检查对比 if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } }

    上面的代码解释了相关的list的分离器和特殊的迭代器.我们从上面的代码可以看出,ArrayList的操作其实是对Object数组的操作.会初始化Object的数组。同时操作会不断的检查expectedModCount.同时添加多个和相应的移除多个是通过Arrays类和System类处理数组的。并且调用迭代器的remove方法的时候,需要lastRet不能为-1,所以需要调用迭代器的next进行给lastRet设置值,不然会抛出异常。(默认lastRet为-1,小于0)

    Processed: 0.043, SQL: 9