导入的函数式接口
import java.util.function.Consumer; // 函数式接口,给定一个参数,对其进行消费处理,处理方式可以是任何操作
例子(以下结果输出12,13),accept方法表示传入定义参数,andThen方法顺序执行处理方式:
public static void consumerExplame()
{
Consumer<Integer> consumer = x -> {
int a = x + 2;
System.out.println(a);
};
Consumer<Integer> consumer2 = x -> {
int a = x + 3;
System.out.println(a);
};
consumer.andThen(consumer2).accept(10);
}
import java.util.function.Predicate;// 函数式接口,接收参数,根据这个参数进行一些处理,返回布尔结果
例子:
public static void predicateExplame()
{
// 过滤条件
Predicate<Integer> predicate = x -> x > 7;
System.out.println(predicate.test(10)); // 输出 true
// 多个过滤条件与
predicate = predicate.and(x -> x % 2 == 0);
System.out.println(predicate.test(8)); // 输出 true
// 多个条件过滤或
predicate = predicate.or(x -> x < 3);
System.out.println(predicate.test(1)); // 输出 true
// 将过滤条件取反
predicate = predicate.negate();
System.out.println(predicate.test(5)); // 输出 true
Predicate<String> predicate2 = Predicate.isEqual("test");
System.out.println(predicate2.test("1"));// 输出false
System.out.println(predicate2.test("test")); // 输出true
}
import java.util.function.UnaryOperator;// 函数式接口,继承Function接口,接收一个泛型T对象,并且返回泛型T对象
例子:
public static void unaryOperatorExplame()
{
UnaryOperator<Integer> dda = x -> x + 1;
System.out.println(dda.apply(1));// 2
UnaryOperator<String> ddb = x -> x + 1;
System.out.println(ddb.apply("aa"));// aa1
}
操作计数:
父类AbstractList中定义protected transient int modCount = 0;记录集合的修改次数,每次变换都会加1,用于迭代器保持单线程唯一操作,如果出现了插入或者删除,就会被迭代器感知,进而抛出异常ConcurrentModificationException,ArrayList是非线程安全的。
/*** 数组为空的时候默认在扩容的时候默认赋予的数组长度*/ private static final int DEFAULT_CAPACITY = 10;
/*** 空数组(1),无最小长度*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/*** 空数组(2),最小长度为10*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/*** 缓冲区数组*/ transient Object[] elementData;
/*** 数组实际长度* @serial*/ private int size;
/*** 构造函数,当参数大于0,按照该参数将缓冲区数组初始化,当参数等于0,将空数组(1)赋值给缓冲区数组,小于0抛出数字不合法异常** @param 数组长度* @throws 数字不合法*/
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);}
}
/*** 未传参数,给缓冲区数组赋值空数组(2)*/
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/*** 构造函数,传参集合,将集合转成数组,并赋值给缓冲区数组,将数组长度赋值给实际长度,如果实际长度不等于0,* 判断数组的类型如果不等于Object类,用Arrays.copyOf将旧缓冲区数组中的元素一一转换成Object类,如果等于0,将空数组(1)赋值给缓冲区数组。* @param 集合* @throws 空指针异常*/
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 {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}
}
/*** 操作计数加1,如果实际长度小于缓冲区数组长度,采用三元运算符,如果实际长度等于0的时候,给缓冲区赋值空数组(1),* 否则使用Arrays.copyOf赋值原缓冲区实际长度的值,主要用作arrayList动态增长的多余容量被删除了,例如分配了10个存储,* 只用了8个,还有2个为null进行去掉*/
public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}
}
/*** 确定数组的长度,用于预先知道数组长度或者大概长度,避免数组不断的扩容,参数传长度minCapacity,获取minExpand:* 如果缓冲区数组不等于空数组(2),minExpand=0,否则,minExpand=默认数组长度10。如果minCapacity >minExpand,* 调用方法ensureExplicitCapacity(minCapacity);,否则不做处理。该方法处理主要用作DEFAULTCAPACITY_EMPTY_ELEMENTDATA数组不能初始长度小于10** @param minCapacity 数组长度*/
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);}
}
/*** 如果缓冲区数组等于空数组(2),从默认长度10和minCapacity取最大值,调用方法ensureExplicitCapacity(minCapacity);* @param minCapacity 长度*/
private void ensureCapacityInternal(int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);
}
/*** 操作计数加1,参数传长度minCapacity,如果minCapacity减去缓冲区数组的长度大于0,调用grow(minCapacity);对数组进行扩容。* @param minCapacity*/
private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);
}/*** 要分配数组的最大大小,一些虚拟机在数组中保存一些头字,分配更大的数组会报OutOfMemoryError错误,内存溢出。*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** 判断是否对数组进行扩容,获取缓冲区数组长度,并将缓冲区长度+缓冲区长度右移一位(除2),* 得到一个新的长度,如果新的长度小于传参长度,新长度等于传参长度,如果新长度大于MAX_ARRAY_SIZE最大长度,* 新长度newCapacity = hugeCapacity(minCapacity);,最后将缓冲区数组使用Arrays.copyOf按新的长度赋值给缓冲区数组。** @param 数组长度*/
private void grow(int minCapacity) {// overflow-conscious codeint 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,抛出内存溢出OutOfMemoryError错误,否则当参数长度大于最大数组大小,返回Integer.MAX_VALUE(某些虚拟机可能内存溢出),否则返回最大数组大小MAX_ARRAY_SIZE。* @param minCapacity 数组长度* @return*/
private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}/*** 返回数组的长度。** @return the number of elements in this list*/
public int size() {return size;
}/*** Returns 判断吧数组的长度是不是等于0.** @return <tt>true</tt> if this list contains no elements*/
public boolean isEmpty() {return size == 0;
}/*** 调用indexOf(参数)方法判断是不是大于等于0.** @param o element whose presence in this list is to be tested* @return <tt>true</tt> if this list contains the specified element*/
public boolean contains(Object o) {return indexOf(o) >= 0;
}/*** 如果参数为null,遍历循环实际长度,* 如果缓冲数组下标为当前迭代等于null的时候,返回当前下标,否则,遍历实际长度,* 如果参数等于缓冲区数组下标为当前迭代的值(equals判断),返回当前下标值,如果没有返回的时候,返回-1.*/
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;
}/*** 调用父类的clone方法,将该数组结构拷贝,将缓冲区数组v.elementData调用Arrays.copyOf缓冲数组elementData,实际长度size,并将操作计数v.modCount设置为0,返回该数组v。** @return a clone of this <tt>ArrayList</tt> instance*/
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 Cloneablethrow new InternalError(e);}
}/*** 使用Arrays.copyOf复制缓冲区数组的实际长度,并进行返回数组。去掉size,去掉操作数** @return an array containing all of the elements in this list in* proper sequence*/
public Object[] toArray() {return Arrays.copyOf(elementData, size);
}/*** 如果a的长度小于实际长度,返回指定参数类型T return (T[]) Arrays.copyOf(elementData, size,* a.getClass());否则复制缓冲区数组,(深度复制)System.arraycopy(elementData, 0, a, 0, size);如果a的长度大于实际长度,a[size] = null,返回a。* @param 泛型数组* @return an array containing the elements of the list* @throws ArrayStoreException if the runtime type of the specified array* is not a supertype of the runtime type of every element in* this list* @throws NullPointerException if the specified array is null*/
@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)// 将最后一个置空,因为最大下标=长度-1a[size] = null;return a;
}// Positional Access Operations/*** 传入数组下标,返回数组这个下标的值,并强制转换相对应类型。这个下标要是验证过的。*/
@SuppressWarnings("unchecked")
E elementData(int index) {return (E) elementData[index];
}/*** 调用rangeCheck(index);方法判断范围,再调用elementData取值。** @param index index of the element to return* @return the element at the specified position in this list* @throws IndexOutOfBoundsException {@inheritDoc}*/
public E get(int index) {rangeCheck(index);return elementData(index);
}/*** 传参index和值,先调用rangeCheck(index);方法判断范围,再取出缓冲区数组当前下标的值,然后对该缓冲区的值进行赋值,返回取出来的值。** @param index index of the element to replace* @param element element to be stored at the specified position* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/
public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;
}/*** 调用ensureCapacityInternal(size + 1);方法将数组长度加1,然后对缓冲区数组size下标赋值,再将实际长度加1,返回true。** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/
public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;
}/*** 调用rangeCheckForAdd(index);判断下标范围,调用ensureCapacityInternal(size + 1); 方法扩容,* 深度拷贝将下标后移一位System.arraycopy(elementData, index, elementData, index + 1,size - index);,将缓冲区数组参数下标的值设置为当前值,并将size+1.** @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++;
}/*** 先调用rangeCheck(index);检查下标范围是否合法,将操作计数+1,取出缓冲区数组参数下标的值,判断后面是否有值int numMoved = size - index - 1;,* 如果numMoved大于0,深度拷贝System.arraycopy(elementData, index+1, elementData, index,numMoved);,并将缓冲区数组下标为最后一个的设置为null,并将size-1,返回取出来的值。** @param index the index of the element to be removed* @return the element that was removed from the list* @throws IndexOutOfBoundsException {@inheritDoc}*/
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 workreturn oldValue;
}/*** 如果参数为null,遍历实际长度,如果缓冲区数组其中有一个为null,* 调用fastRemove(index);删除,并返回true,否则遍历实际长度,如果参数等于缓冲区数组的其中一个,调用fastRemove(index);方法返回true,否则,返回false。** @param o element to be removed from this list, if present* @return <tt>true</tt> if this list contained the specified element*/
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;
}/** 操作计数加1,获取后面是否有删除的长度,int numMoved = size - index - 1;如果长度大于0,* 深拷贝将所有后面的值往前移,System.arraycopy(elementData, index+1, elementData, index,numMoved);并将缓冲区数组最后一个设置成null,并--size。*/
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
}/*** 操作计数加1,循环实际长度,将缓冲区数组遍历设置成null,并将实际长度设置为0.*/
public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;
}/*** 将c转换成数组Object[] a = c.toArray();获取a的长度,调用ensureCapacityInternal(size + numNew);* 方法对缓冲区数组进行扩容,并将a深度拷贝至缓冲区数组System.arraycopy(a, 0, elementData, size, numNew);,把实际长度加上c数组长度,返回c数组长度的值不等于0.** @param c collection containing elements to be added to this list* @return <tt>true</tt> if this list changed as a result of the call* @throws NullPointerException if the specified collection is null*/
public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountSystem.arraycopy(a, 0, elementData, size, numNew);size += numNew;return numNew != 0;
}/*** 检查下标的范围rangeCheckForAdd(index);,将c转成数组Object[] a = c.toArray();,获取数组长度,* 调用ensureCapacityInternal(size + numNew);对缓冲区数组进行扩容,获取往后移的数组个数,* 深度拷贝往后移System.arraycopy(elementData, index, elementData, index + numNew,numMoved);深度拷贝进行赋值System.arraycopy(a, 0, elementData, index, numNew);* 将数组长度+实际长度,返回数组长度不等于0.** @param index index at which to insert the first element from the* specified collection* @param c collection containing elements to be added to this list* @return <tt>true</tt> if this list changed as a result of the call* @throws IndexOutOfBoundsException {@inheritDoc}* @throws NullPointerException if the specified collection is null*/
public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountint 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;
}/*** 将操作计数加1,获取要移动的元素长度int numMoved = size - toIndex;深拷贝移动元素* System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);获取新的实际长度,循环数据长度,将缓冲区数组该下标都设置成null,将实际长度赋值新实际长度。** @throws IndexOutOfBoundsException if {@code fromIndex} or* {@code toIndex} is out of range* ({@code fromIndex < 0 ||* fromIndex >= size() ||* toIndex > size() ||* toIndex < fromIndex})*/
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 workint newSize = size - (toIndex-fromIndex);for (int i = newSize; i < size; i++) {elementData[i] = null;}size = newSize;
}/***判断传入参数index是不是大于实际长度,如果大于等于,抛出数组下标越界异常。*/
private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}/*** 断下标如果大于实际长度或者下标小于0,抛出数组下标越界异常,并将size+1。*/
private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}/*** 返回return "Index: "+index+", Size: "+size;下标和实际长度。*/
private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;
}/*** 方法判断集合是否为空,返回 return batchRemove(c, false);方法** @param c collection containing elements to be removed from this list* @return {@code true} if this list changed as a result of the call* @throws ClassCastException if the class of an element of this list* is incompatible with the specified collection* (<a href="Collection.html#optional-restrictions">optional</a>)* @throws NullPointerException if this list contains a null element and the* specified collection does not permit null elements* (<a href="Collection.html#optional-restrictions">optional</a>),* or if the specified collection is null* @see Collection#contains(Object)*/
public boolean removeAll(Collection<?> c) {Objects.requireNonNull(c);return batchRemove(c, false);
}/***方法判断集合是否为空,返回 return batchRemove(c, true);方法。** @param c collection containing elements to be retained in this list* @return {@code true} if this list changed as a result of the call* @throws ClassCastException if the class of an element of this list* is incompatible with the specified collection* (<a href="Collection.html#optional-restrictions">optional</a>)* @throws NullPointerException if this list contains a null element and the* specified collection does not permit null elements* (<a href="Collection.html#optional-restrictions">optional</a>),* or if the specified collection is null* @see Collection#contains(Object)*/
public boolean retainAll(Collection<?> c) {Objects.requireNonNull(c);return batchRemove(c, true);
}/*** 使用final定义一个新数组,将缓冲区数组赋值给新数组,定义两个变量r、w等于0,* 定义修改状态为false,try遍历实际长度,使用变量r作为下标,如果集合c包含定义常量的某一个值,并等于参数布尔状态,将定义常量的下标w++赋值缓冲区数组下标r,* (当布尔状态为false的时候,将所有参数集合和新数组不交集的值放至最前面,当布尔状态为false的时候,将所有参数集合和新数组交集的值放至最前面),finally最终处理* 防止contains异常,如果r!=size,深拷贝将w后的数据拷贝到新数组,将w+=size - r;如果w != size,遍历实际长度,将大于w的下标的值都设成null,并将操作次数+size-w次,* 将w赋值给最新长度,并标记修改状态为true,返回修改状态。* @param c* @param complement* @return*/
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 workfor (int i = w; i < size; i++)elementData[i] = null;modCount += size - w;size = w;modified = true;}}return modified;
}/*** 方法定义的抛出IO输入输出异常,首先定义常数操作次数,* 然后调用IO的defaultWriteObject方法将除了transient的其它数据序列化,再将数组大小序列化,* 然后再把元素一个个的序列化,如果操作次数不等于常数,抛出在排序期间有进行修改数组的异常。** @serialData The length of the array backing the <tt>ArrayList</tt>* instance is emitted (int), followed by all of its elements* (each an <tt>Object</tt>) in the proper order.*/
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}
}/*** 参数传入IO流的ObjectInputStream,方法定义的抛出IO异常、类找不到异常,首先定义缓冲区数组为空数组(1),* 将除了transient的其它数据反序列化,再将数组长度反序列化,如果实际长度大于0,调用ensureCapacityInternal(size);对数组进行扩容,* 定义一个常数数组,将缓冲区数组赋值给常数数组,循环实际长度,给每个下标赋值a[i] = s.readObject();。*/
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}}
}/*** 如果下标小于0或者下标大于实际长度的时候,抛出数组下标越界异常,返回对象return new ListItr(index);。** <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @throws IndexOutOfBoundsException {@inheritDoc}*/
public ListIterator<E> listIterator(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);return new ListItr(index);
}/*** 返回对象return new ListItr(0);。** <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @see #listIterator(int)*/
public ListIterator<E> listIterator() {return new ListItr(0);
}/*** 返回对象return new Itr();。** <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @return an iterator over the elements in this list in proper sequence*/
public Iterator<E> iterator() {return new Itr();
}/*** An optimized version of AbstractList.Itr*/
private class Itr implements Iterator<E> {int cursor; // 定义下一个要访问的元素下标int lastRet = -1; // 定义上一个要访问的元素下标int expectedModCount = modCount; // 定义常数接收操作次数public boolean hasNext() {return cursor != size;}@SuppressWarnings("unchecked")public E next() {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];}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}@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++]);}// update once at end of iteration to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}
}/*** An optimized version of AbstractList.ListItr*/
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];}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();}}
}/*** 调用subListRangeCheck(fromIndex, toIndex, size);方法检查,返回对象new SubList(this, 0, fromIndex, toIndex);。** @throws IndexOutOfBoundsException {@inheritDoc}* @throws IllegalArgumentException {@inheritDoc}*/
public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);
}/*** 如果开始下标小于0,抛出数组下标越界异常,如果结束下标大于实际长度,抛出数组下标越界异常,如果开始下标大于结束下标,抛出数据不合法异常。* @param fromIndex* @param toIndex* @param size*/
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 + ")");
}private class SubList extends AbstractList<E> implements RandomAccess {private final AbstractList<E> parent;private final int parentOffset;private final int offset;int size;SubList(AbstractList<E> parent,int offset, int fromIndex, int toIndex) {this.parent = parent;this.parentOffset = fromIndex;this.offset = offset + fromIndex;this.size = toIndex - fromIndex;this.modCount = ArrayList.this.modCount;}public E set(int index, E e) {rangeCheck(index);checkForComodification();E oldValue = ArrayList.this.elementData(offset + index);ArrayList.this.elementData[offset + index] = e;return oldValue;}public E get(int index) {rangeCheck(index);checkForComodification();return ArrayList.this.elementData(offset + index);}public int size() {checkForComodification();return this.size;}public void add(int index, E e) {rangeCheckForAdd(index);checkForComodification();parent.add(parentOffset + index, e);this.modCount = parent.modCount;this.size++;}public E remove(int index) {rangeCheck(index);checkForComodification();E result = parent.remove(parentOffset + index);this.modCount = parent.modCount;this.size--;return result;}protected void removeRange(int fromIndex, int toIndex) {checkForComodification();parent.removeRange(parentOffset + fromIndex,parentOffset + toIndex);this.modCount = parent.modCount;this.size -= toIndex - fromIndex;}public boolean addAll(Collection<? extends E> c) {return addAll(this.size, c);}public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);int cSize = c.size();if (cSize==0)return false;checkForComodification();parent.addAll(parentOffset + index, c);this.modCount = parent.modCount;this.size += cSize;return true;}public Iterator<E> iterator() {return listIterator();}public ListIterator<E> listIterator(final int index) {checkForComodification();rangeCheckForAdd(index);final int offset = this.offset;return new ListIterator<E>() {int cursor = index;int lastRet = -1;int expectedModCount = ArrayList.this.modCount;public boolean hasNext() {return cursor != SubList.this.size;}@SuppressWarnings("unchecked")public E next() {checkForComodification();int i = cursor;if (i >= SubList.this.size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[offset + (lastRet = i)];}public boolean hasPrevious() {return cursor != 0;}@SuppressWarnings("unchecked")public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[offset + (lastRet = i)];}@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = SubList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[offset + (i++)]);}// update once at end of iteration to reduce heap write trafficlastRet = cursor = i;checkForComodification();}public int nextIndex() {return cursor;}public int previousIndex() {return cursor - 1;}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {SubList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void set(E e) {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.set(offset + lastRet, e);} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void add(E e) {checkForComodification();try {int i = cursor;SubList.this.add(i, e);cursor = i + 1;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (expectedModCount != ArrayList.this.modCount)throw new ConcurrentModificationException();}};}public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, offset, fromIndex, toIndex);}private void rangeCheck(int index) {if (index < 0 || index >= this.size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private void rangeCheckForAdd(int index) {if (index < 0 || index > this.size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+this.size;}private void checkForComodification() {if (ArrayList.this.modCount != this.modCount)throw new ConcurrentModificationException();}public Spliterator<E> spliterator() {checkForComodification();return new ArrayListSpliterator<E>(ArrayList.this, offset,offset + this.size, this.modCount);}
}/*** 首先检测集合是否存在,定义常数操作数等于操作数,定义一个数组等于缓冲区数组,* 定义一个变量等于实际长度,循环实际长度,并且操作数正确,将常数数组接收,如果操作数不相等,抛出数组修改操作数异常。* @param 参数为consumer类型,传参进去无返回值按照穿进去的方法进行处理*/
@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();}
}/*** 返回对象return new ArrayListSpliterator<>(this, 0, -1, 0);。** @return a {@code Spliterator} over the elements in this list* @since 1.8*/
@Override
public Spliterator<E> spliterator() {return new ArrayListSpliterator<>(this, 0, -1, 0);
}/** Index-based split-by-two, lazily initialized Spliterator */
static final class ArrayListSpliterator<E> implements Spliterator<E> {/** If ArrayLists were immutable, or structurally immutable (no* adds, removes, etc), we could implement their spliterators* with Arrays.spliterator. Instead we detect as much* interference during traversal as practical without* sacrificing much performance. We rely primarily on* modCounts. These are not guaranteed to detect concurrency* violations, and are sometimes overly conservative about* within-thread interference, but detect enough problems to* be worthwhile in practice. To carry this out, we (1) lazily* initialize fence and expectedModCount until the latest* point that we need to commit to the state we are checking* against; thus improving precision. (This doesn't apply to* SubLists, that create spliterators with current non-lazy* values). (2) We perform only a single* ConcurrentModificationException check at the end of forEach* (the most performance-sensitive method). When using forEach* (as opposed to iterators), we can normally only detect* interference after actions, not before. Further* CME-triggering checks apply to all other possible* violations of assumptions for example null or too-small* elementData array given its size(), that could only have* occurred due to interference. This allows the inner loop* of forEach to run without any further checks, and* simplifies lambda-resolution. While this does entail a* number of checks, note that in the common case of* list.stream().forEach(a), no checks or other computation* occur anywhere other than inside forEach itself. The other* less-often-used methods cannot take advantage of most of* these streamlinings.*/private final ArrayList<E> list;private int index; // current index, modified on advance/splitprivate int fence; // -1 until used; then one past last indexprivate int expectedModCount; // initialized when fence set/** Create new spliterator covering the given range */ArrayListSpliterator(ArrayList<E> list, int origin, int fence,int expectedModCount) {this.list = list; // OK if null unless traversedthis.index = origin;this.fence = fence;this.expectedModCount = expectedModCount;}private int getFence() { // initialize fence to size on first useint hi; // (a specialized variant appears in method 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 : // divide range in half unless too smallnew 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 loopArrayList<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;}elsemc = 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;}
}/*** 检测集合是否存在,定义删除总数量变量等于0,定义删除数据BitSet集合。定义常数操作数等于操作数,定义长度等于实际长度,* 遍历循环实际长度,如果操作数正确,定义一个元素接收缓冲区数组下标的值,如果检验参数有这个元素,将这个元素的下标放入删除集合,删除个数+1,如果操作次数不相符,* 抛出操作次数异常,定义布尔常数等于删除个数大于0,如果这个布尔参数为真,定义新的长度等于实际长度减去要删除的个数,循环新长度并且实际长度,* 将缓冲区数组的值进行修改,将多余的遍历为null,将新长度赋值给实际长度,如果操作次数有异常抛出异常,无就将操作次数加1,并且返回布尔状态。* @param 传参Predicate(处理方法,lamda表达式),传参返回布尔值* @return*/
@Override
public boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);// figure out which elements are to be removed// any exception thrown from the filter predicate at this stage// will leave the collection unmodifiedint 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();}// shift surviving elements left over the spaces left by removed elementsfinal 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; // Let gc do its work}this.size = newSize;if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;}return anyToRemove;
}/*** 首先使用Objects.requireNonNull(operator);判断集合是否为空,定义一个常数等于操作次数,* 定义一个常数等于实际长度,遍历循环常数实际长度,判断条件常数操作次数与操作次数相等,以防替换数据的时候有进行修改,* 将数据进行替换elementData[i] = operator.apply((E) elementData[i]);,如果常数操作次数不等于操作次数,抛出数组有修改异常,无异常将操作次数进行加1。* @param 传什么类型的参数返回什么值,参数里面是执行方法(例:list.replaceAll(a->a.equals("zhangsan")?"张三":a);)*/
@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++;
}/*** 定义一个常数等于操作次数,调用Arrays.sort((E[]) elementData, 0, size, c);方法进行排序,如果操作次数不等于常数,抛出在排序期间有进行修改数组的异常,无异常抛出就将操作次数。* @param c*/
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {final int expectedModCount = modCount;Arrays.sort((E[]) elementData, 0, size, c);if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;
}