免费表格模板网站建设视频网站的视频源

news/2025/9/24 9:56:25/文章来源:
免费表格模板网站,建设视频网站的视频源,分类网站一天做几条合适,平度建设网站ArrayList 基于数组实现#xff0c;无容量的限制。 在执行插入元素时可能要扩容#xff0c;在删除元素时并不会减小数组的容量#xff0c;在查找元素时要遍历数组#xff0c;对于非null的元素采取equals的方式寻找。 是非线程安全的。 注意点#xff1a; #xff08…  ArrayList 基于数组实现无容量的限制。 在执行插入元素时可能要扩容在删除元素时并不会减小数组的容量在查找元素时要遍历数组对于非null的元素采取equals的方式寻找。 是非线程安全的。 注意点 1ArrayList随机存取元素时间复杂度O(1)插入删除操作需大量移动元素效率较低 2为了节约内存当新建容器为空时会共享 Object[] EMPTY_ELEMENTDATA {}和 Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {}空数组 3容器底层采用数组存储每次扩容为1.5倍 4ArrayList的实现中大量地调用了Arrays.copyof()和System.arraycopy()方法其实Arrays.copyof()内部也是调用System.arraycopy()。System.arraycopy()为Native方法 5两个ToArray方法 Object[] toArray()方法。该方法有可能会抛出java.lang.ClassCastException异常 T T[] toArray(T[] a)方法。该方法可以直接将ArrayList转换得到的Array进行整体向下转型 6ArrayList可以存储null值 7ArrayList每次修改增加、删除容器时都是修改自身的modCount在生成迭代器时迭代器会保存该modCount值迭代器每次获取元素时会比较自身的modCount与ArrayList的modCount是否相等来判断容器是否已经被修改如果被修改了则抛出异常fast-fail机制。 源码解析 package java.util;import sun.misc.SharedSecrets; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator;public class ArrayListE extends AbstractListEimplements ListE, RandomAccess, Cloneable, java.io.Serializable {private static final long serialVersionUID 8683452581122892189L;/*** 默认容量*/private static final int DEFAULT_CAPACITY 10;/*** 对象数组*/private static final Object[] EMPTY_ELEMENTDATA {};/*** 默认的空数组无参构造函数创建的数组*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {};/*** 存放数据的数组的缓存变量*/transient Object[] elementData;/*** 元素数量* */private int size;/*** 带有容量的构造方法* * param 数组的初始容量* throws IllegalArgumentException 参数为负*/public ArrayList(int initialCapacity) {// 参数0if (initialCapacity 0) {// new一个object数组赋给elementDatathis.elementData new Object[initialCapacity];} else if (initialCapacity 0) {// 参数0// 将空数组赋给elementDatathis.elementData EMPTY_ELEMENTDATA;} else {//参数0,抛出IllegalArgumentException异常throw new IllegalArgumentException(Illegal Capacity: initialCapacity);}}/*** 不带参数构造方法*/public ArrayList() {// 将空数组赋给elementDatathis.elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}/*** 带参数Collection的构造方法* * param c* 其元素将被放入此列表中的集合* throws NullPointerException* 集合为空*/public ArrayList(Collection? extends E c) {elementData c.toArray();if ((size elementData.length) ! 0) {// c.toArray可能错误地不返回对象[]JAVA BUG编号6260652if (elementData.getClass() ! Object[].class)// Array.copyOf()主要用来将原数组拷贝到一个新的数组适用于数组扩容。elementData Arrays.copyOf(elementData, size, Object[].class);} else {// 空数组this.elementData EMPTY_ELEMENTDATA;}}/*** 因为容量基本会大于实际元素的数量。内存紧张时可以调用该方法调整容量为元素实际数量。* 如果确定不会有元素添加进来时也可以调用该方法来节约空间*/public void trimToSize() {modCount;// 如果size小于lengthif (size elementData.length) {// 将elementData设置大小为sizeelementData (size 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}/*** 使用指定参数设置数组容量* * param minCapacity* 所需的最小容量*/public void ensureCapacity(int minCapacity) {// 如果数组为空容量预取0否则去默认值(10)int minExpand (elementData ! DEFAULTCAPACITY_EMPTY_ELEMENTDATA)// any size if not default element table? 0// larger than default for default empty table. Its already// supposed to be at default size.: DEFAULT_CAPACITY;// 若参数大于预设的容量再使用该参数进一步设置数组容量if (minCapacity minExpand) {ensureExplicitCapacity(minCapacity);}}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}/*** 得到最小扩容量* * param minCapacity*/private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}/*** 判断是否需要扩容* * param minCapacity*/private void ensureExplicitCapacity(int minCapacity) {modCount;// 最小需要空间比elementData的内存空间大if (minCapacity - elementData.length 0)grow(minCapacity);}/*** 数组的最大容量可能会导致内存溢出*/private static final int MAX_ARRAY_SIZE Integer.MAX_VALUE - 8;/*** 扩容* * param minCapacity* 所需的最小容量*/private void grow(int minCapacity) {// ArrayList中elementData的内存空间长度int oldCapacity elementData.length;// 扩容原来的1.5倍int newCapacity oldCapacity (oldCapacity 1);// 判断新数组的容量够不够// 不够就将数组长度设置为需要的长度if (newCapacity - minCapacity 0)newCapacity minCapacity;// 预设值默认的最大值,检查溢出if (newCapacity - MAX_ARRAY_SIZE 0)newCapacity hugeCapacity(minCapacity);// 放到新数组中elementData Arrays.copyOf(elementData, newCapacity);}/*** 检查是否溢出若没有溢出返回最大整数值或默认最大值* * param minCapacity* return*/private static int hugeCapacity(int minCapacity) {if (minCapacity 0) // 溢出throw new OutOfMemoryError();return (minCapacity MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}/*** 返回ArrayList的大小* * return ArrayList中的元素数量*/public int size() {return size;}/*** 返回是否为空* * return true 如果ArrayList中无元素*/public boolean isEmpty() {return size 0;}/*** 是否包含一个数 返回bool* * param o* 被检查元素* return true 如果ArrayList中包含o元素*/public boolean contains(Object o) {return indexOf(o) 0;}/*** 返回一个值首次出现的位置不存在就返回-1。时间复杂度O(N)* * 返回第一个null* param o* return*/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。时间复杂度O(N)* 返回最后一个null* param o* return*/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;}/*** 返回副本元素本身没有被复制复制过程中数组发生改变会抛出异常* * return v ArrayList副本*/public Object clone() {try {// 调用Object类的clone方法得到ArrayList副本ArrayList? v (ArrayList?) super.clone();// 调用copyOf将ArrayList的elementData数组赋给副本的elementData数组v.elementData Arrays.copyOf(elementData, size);v.modCount 0;return v;} catch (CloneNotSupportedException e) {// this shouldnt happen, since we are Cloneablethrow new InternalError(e);}}/*** 转换为Object数组* * return 一个数组包含所有列表中的元素*/public Object[] toArray() {return Arrays.copyOf(elementData, size);}/*** 将ArrayList里面的元素赋值到一个数组中去* a的长度小于ArrayList的长度直接调用Arrays类的copyOf* a的长度大于ArrayList的长度调用System.arraycopy然后把size位置赋值为空。* * param a* 如果它的长度大的话列表元素存储在这个数组中; 否则分配一个新数组。* return 一个包含ArrayList元素的数组* throws ArrayStoreException* 将与数组类型不兼容的值赋值给数组元素时抛出的异常* throws NullPointerException* 数组为空*/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;}/*** 返回指定位置的值* param index* return*/SuppressWarnings(unchecked)E elementData(int index) {return (E) elementData[index];}/*** 返回指定位置的值先检查是否超出数组长度* * param index* 元素的索引* return ArrayList中指定位置的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E get(int index) {// 检查是否越界rangeCheck(index);// 返回ArrayList的elementData数组index位置的元素return elementData(index);}/*** 设置指定位置为一个新值返回之前的值* * param index* 要替换的元素的索引* param element* 要存储在指定位置的元素* return 之前在指定位置的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E set(int index, E element) {// 检查越界rangeCheck(index);// 获取当前位置的值E oldValue elementData(index);// 将element赋值到index位置elementData[index] element;return oldValue;}/*** 添加一个值首先会确保容量* * param e* 要添加到此列表中的元素* return tttrue/tt (as specified by {link Collection#add})*/public boolean add(E e) {// 扩容ensureCapacityInternal(size 1);// 将e赋值给elementData的size1的位置elementData[size] e;return true;}/*** index位置添加元素element会检查添加的位置和容量* * param index* 指定元素将被插入的索引* param element* 要插入的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public void add(int index, E element) {// 判断越界rangeCheckForAdd(index);// 扩容ensureCapacityInternal(size 1); // Increments modCount!!// 将elementData从index位置开始复制到elementData的index1开始的连续空间System.arraycopy(elementData, index, elementData, index 1,size - index);// 在index位置赋值elementelementData[index] element;// ArrayList的大小size;}/*** 移除index位置的元素,会检查去除的位置* * param index* 要删除的元素的索引* return 删除的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E remove(int index) {// 判断越界rangeCheck(index);modCount;// 读取旧值E oldValue elementData(index);// 获取index位置开始到最后一个位置的个数int numMoved size - index - 1;if (numMoved 0)// index1位置开始拷贝到从index开始的空间System.arraycopy(elementData, index 1, elementData, index,numMoved);elementData[--size] null; // 便于垃圾回收器回收return oldValue;}/*** 移除对象为O的元素跟indexOf方法思想基本一致* param o* 要从该列表中删除的元素如果存在* return true 如果这个列表包含指定的元素*/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;}/*** 快速删除指定位置的值不需要检查和返回值* * param index*/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,方便垃圾回收(不同于reset数组默认大小有改变的话不会重置)*/public void clear() {modCount;// 便于垃圾回收器回收for (int i 0; i size; i)elementData[i] null;size 0;}/*** 添加一个集合的元素到末端* * param c* 包含要添加到此列表中的元素的集合* return true 如果该列表因添加而改变* throws NullPointerException* 如果指定的集合是空的*/public boolean addAll(Collection? extends E c) {// c转换为数组aObject[] a c.toArray();// a占的内存空间长度赋值给numNewint numNew a.length;// 扩容至size numNewensureCapacityInternal(size numNew);// 将a的第0位开始拷贝至elementData的size位开始拷贝长度为numNewSystem.arraycopy(a, 0, elementData, size, numNew);// 将size增加numNewsize numNew;return numNew ! 0;}/*** 从第index位开始将c全部拷贝到ArrayList* * param index* 在哪个索引开始插入* param c* 包含要添加到此列表中的元素的集合* return true 如果该列表因添加而改变* throws IndexOutOfBoundsException* {inheritDoc}* throws NullPointerException* 如果指定的集合是空的*/public boolean addAll(int index, Collection? extends E c) {rangeCheckForAdd(index);// 将c转换为数组aObject[] a c.toArray();int numNew a.length;// 扩容至size numNewensureCapacityInternal(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;}/*** 删除指定范围元素。* * 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);// 便于垃圾回收int newSize size - (toIndex - fromIndex);for (int i newSize; i size; i) {elementData[i] null;}size newSize;}/*** 检查index是否超出数组长度*/private void rangeCheck(int index) {// 如果下标超过ArrayList的数组长度if (index size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 检查是否溢出*/private void rangeCheckForAdd(int index) {if (index size || index 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 抛出的异常的详情*/private String outOfBoundsMsg(int index) {return Index: index , Size: size;}/*** ArrayList移除集合c中的所有元素* * param c* 包含要从此列表中移除的元素的集合* return {code true} 如果该列表因移除而改变* throws ClassCastException* if the class of an element of this list is incompatible with* the specified collection (a* hrefCollection.html#optional-restrictionsoptional/a)* throws NullPointerException* if this list contains a null element and the specified* collection does not permit null elements (a* hrefCollection.html#optional-restrictionsoptional/a),* or if the specified collection is null* see Collection#contains(Object)*/public boolean removeAll(Collection? c) {// 如果c为空则抛出空指针异常Objects.requireNonNull(c);// 调用batchRemove移除c中的元素return batchRemove(c, false);}/*** 仅保留指定集合c中的元素* * 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* hrefCollection.html#optional-restrictionsoptional/a)* throws NullPointerException* if this list contains a null element and the specified* collection does not permit null elements (a* hrefCollection.html#optional-restrictionsoptional/a),* or if the specified collection is null* see Collection#contains(Object)*/public boolean retainAll(Collection? c) {Objects.requireNonNull(c);// 调用batchRemove保留c中的元素return batchRemove(c, true);}/*** 根据complement值将ArrayList中包含c中元素的元素删除或者保留* * param c* param complement* true时从数组保留指定集合中元素的值为false时从数组删除指定集合中元素的值。* return 数组中重复的元素都会被删除(而不是仅删除一次或几次)有任何删除操作都会返回true*/private boolean batchRemove(Collection? c, boolean complement) {final Object[] elementData this.elementData;// 定义一个w一个r两个同时右移int r 0, w 0;boolean modified false;try {// r先右移for (; r size; r)// 如果c中不包含elementData[r]这个元素if (c.contains(elementData[r]) complement)// 则直接将r位置的元素赋值给w位置的元素w自增elementData[w] elementData[r];} finally {// 防止抛出异常导致上面r的右移过程没完成if (r ! size) {// 将r未右移完成的位置的元素赋值给w右边位置的元素System.arraycopy(elementData, r,elementData, w,size - r);// 修改w值增加size-rw size - r;}// 如果有被覆盖掉的元素则将w后面的元素都赋值为nullif (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;}/*** 保存数组实例的状态到一个流即序列化。写入过程数组被更改会抛出异常* * serialData The length of the array backing the ttArrayList/tt* instance is emitted (int), followed by all of its elements* (each an ttObject/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();// 写入大小s.writeInt(size);// 写入所有元素for (int i 0; i size; i) {s.writeObject(elementData[i]);}if (modCount ! expectedModCount) {throw new ConcurrentModificationException();}}/*** 从流中重构ArrayList实例即反序列化。*/private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData EMPTY_ELEMENTDATA;// 执行默认的序列化/反序列化过程s.defaultReadObject();// 读入数组长度s.readInt(); // ignoredif (size 0) {int capacity calculateCapacity(elementData, size);SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);ensureCapacityInternal(size);Object[] a elementData;// 读入所有元素for (int i 0; i size; i) {a[i] s.readObject();}}}/*** 返回一个从index开始的ListIterator对象* * throws IndexOutOfBoundsException* {inheritDoc}*/public ListIteratorE listIterator(int index) {if (index 0 || index size)throw new IndexOutOfBoundsException(Index: index);return new ListItr(index);}/*** 返回一个ListIterator对象ListItr为ArrayList的一个内部类实现了ListIteratorE 接口* * see #listIterator(int)*/public ListIteratorE listIterator() {return new ListItr(0);}/*** 返回一个Iterator对象Itr为ArrayList的一个内部类实现了IteratorE接口* * return an iterator over the elements in this list in proper sequence*/public IteratorE iterator() {return new Itr();}/*** 通用的迭代器实现*/private class Itr implements IteratorE {int cursor; // 下一个元素的索引默认为0int 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();}}OverrideSuppressWarnings(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();}}/*** ListIterator迭代器实现*/private class ListItr extends Itr implements ListIteratorE {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();}}}/*** * 该方法返回的是父list的一个视图fromIndex包含到toIndex不包含。fromIndextoIndex 表示子list为空*/public ListE subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);}/*** 安全检查* * 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 AbstractListE implements RandomAccess {private final AbstractListE parent;private final int parentOffset;private final int offset;int size;SubList(AbstractListE 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 IteratorE iterator() {return listIterator();}public ListIteratorE listIterator(final int index) {checkForComodification();rangeCheckForAdd(index);final int offset this.offset;return new ListIteratorE() {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();}};}/*** 返回指定范围的子数组* * param fromIndex* param toIndex* return*/public ListE 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 SpliteratorE spliterator() {checkForComodification();return new ArrayListSpliteratorE(ArrayList.this, offset,offset this.size, this.modCount);}}/*** Java 8 lambda 使用流遍历数组*/Overridepublic 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 a {code Spliterator} over the elements in this list* since 1.8*/Overridepublic SpliteratorE spliterator() {return new ArrayListSpliterator(this, 0, -1, 0);}/*** Index-based split-by-two, lazily initialized Spliterator*/static final class ArrayListSpliteratorE implements SpliteratorE {/** //forEachprivate final ArrayListE 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(ArrayListE 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)ArrayListE lst;if ((hi fence) 0) {if ((lst list) null)hi fence 0;else {expectedModCount lst.modCount;hi fence lst.size;}}return hi;}public ArrayListSpliteratorE trySplit() {int hi getFence(), lo index, mid (lo hi) 1;return (lo mid) ? null : // divide range in half unless too smallnew ArrayListSpliteratorE(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 loopArrayListE 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;}}Overridepublic 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;}OverrideSuppressWarnings(unchecked)public void replaceAll(UnaryOperatorE 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;}OverrideSuppressWarnings(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;} } LinkedList java.lang.Objectjava.util.AbstractCollectionEjava.util.AbstractListEjava.util.AbstractSequentialListEjava.util.LinkedListE List 接口的链接列表实现。实现所有可选的列表操作并且允许所有元素包括 null。 除了实现 List 接口外LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。 此类实现 Deque 接口为 add、poll 提供先进先出队列操作以及其他堆栈和双端队列操作。 所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表从靠近指定索引的一端。 操作效率大部分效率都是o(n)的 同步 注意此实现不是同步的。如果多个线程同时访问一个链接列表而其中至少一个线程从结构上修改了该列表则它必须 保持外部同步。结构修改指添加或删除一个或多个元素的任何操作仅设置元素的值不是结构修改。这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象则应该使用 Collections.synchronizedList 方法来“包装”该列表。最好在创建时完成这一操作以防止对列表进行意外的不同步访问如下所示 List list Collections.synchronizedList(new LinkedList(...)); iterator 此类的 iterator 和 listIterator 方法返回的迭代器是快速失败 的在迭代器创建之后如果从结构上对列表进行修改除非通过迭代器自身的 remove 或 add 方法其他任何时间任何方式的修改迭代器都将抛出 ConcurrentModificationException。因此面对并发的修改迭代器很快就会完全失败而不冒将来不确定的时间任意发生不确定行为的风险。 注意迭代器的快速失败行为不能得到保证一般来说存在不同步的并发修改时不可能作出任何硬性保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此编写依赖于此异常的程序的方式是错误的正确做法是迭代器的快速失败行为应该仅用于检测程序错误。 源码解析 package java.util; import java.util.function.Consumer; public class LinkedListEextends AbstractSequentialListEimplements ListE, DequeE, Cloneable, java.io.Serializable {/*** 元素数量*/transient int size 0;/*** 首结点引用*/transient NodeE first;/*** 尾节点引用*/transient NodeE last;/*** 无参构造方法*/public LinkedList() {}/*** 通过一个集合初始化元素顺序有这个集合的迭代器返回顺序决定* * param c* 其元素将被放入此列表中的集合* throws NullPointerException* 如果指定的集合是空的*/public LinkedList(Collection? extends E c) {// 调用无参构造this();// 添加所有的元素addAll(c);}/*** 头插内部使用*/private void linkFirst(E e) {// 当前首结点final NodeE f first;// 构建新节点final NodeE newNode new Node(null, e, f);// 将newNode作为首节点first newNode;// 如果原首节点为null即原链表为null则链表尾节点也设置为newNodeif (f null)last newNode;else // 否则原首节点的prev设置为newNodef.prev newNode;size; // 长度1modCount; // 修改次数1}/*** 尾插*/void linkLast(E e) {// 获取尾结点final NodeE l last;// 构建新节点final NodeE newNode new Node(l, e, null);// newNode作为尾节点last newNode;// 如果原尾节点为null即原链表为null则链表首节点也设置为newNodeif (l null)first newNode;else // 否则原尾节点的next设置为newNodel.next newNode;size;modCount;}/*** 在非空节点succ前插入节点值e*/void linkBefore(E e, NodeE succ) {final NodeE pred succ.prev;// 构建新节点final NodeE newNode new Node(pred, e, succ);// 设置newNode为succ的前节点succ.prev newNode;// 如果succ.prev为null即succ为首节点则将newNode设置为首节点if (pred null)first newNode;else // 如果succ不是首节点pred.next newNode;size;modCount;}/*** 删除首结点返回存储的元素内部使用*/private E unlinkFirst(NodeE f) {// 获取首结点存储的元素final E element f.item;// 获取首结点的后继结点final NodeE next f.next;// 删除首结点f.item null;f.next null; // 便于垃圾回收// 首结点后继结点设为首结点first next;// 如果原来首结点的后继结点为空则尾结点设为null// 否则原来首结点的后继结点的前驱结点设为nullif (next null)last null;elsenext.prev null;size--;modCount;// 返回原来首结点存储的元素return element;}/*** 删除尾结点返回存储的元素内部使用*/private E unlinkLast(NodeE l) {// 获取尾结点存储的元素final E element l.item;// 获取尾结点的前驱结点final NodeE prev l.prev;// 删除尾结点l.item null;l.prev null; // help GC// 原来尾结点的前驱结点设为尾结点last prev;// 如果原来尾结点的前驱结点为空则首结点设为null// 否则原来尾结点的前驱结点的后继结点设为nullif (prev null)first null;elseprev.next null;size--;modCount;// 返回原来尾结点存储的元素return element;}/*** 删除指定非空结点返回存储的元素*/E unlink(NodeE x) {// 获取指定非空结点存储的元素final E element x.item;// 获取指定非空结点的后继结点final NodeE next x.next;// 获取指定非空结点的前驱结点final NodeE prev x.prev;/*** 如果指定非空结点的前驱结点为空则指定非空结点的后继结点设为首结点 * 否则指定非空结点的后继结点设为指定非空结点的前驱结点的后继结点* 指定非空结点的前驱结点设为null*/if (prev null) {first next;} else {prev.next next;x.prev null;}/*** 如果指定非空结点的后继结点为空则指定非空结点的前驱结点设为尾结点 * 否则指定非空结点的前驱结点设为指定非空结点的后继结点的前驱结点* 指定非空结点的后继结点设为null*/if (next null) {last prev;} else {next.prev prev;x.next null;}// 指定非空结点存储的元素设为nullx.item null;size--;modCount;// 返回指定非空结点存储的元素return element;}/*** 获取首结点存储的元素* * return 首结点存储的元素* throws NoSuchElementException* 如果链表为空*/public E getFirst() {// 获取首结点引用final NodeE f first;// 如果首结点为空则抛出无该元素异常if (f null)throw new NoSuchElementException();// 返回首结点存储的元素return f.item;}/*** 获取尾结点存储的元素* * return 尾结点存储的元素* throws NoSuchElementException* 如果链表为空*/public E getLast() {// 获取尾结点引用final NodeE l last;// 如果尾结点为空则抛出无该元素异常if (l null)throw new NoSuchElementException();// 返回尾结点存储的元素return l.item;}/*** 删除首结点返回存储的元素* * return 首结点存储的元素* throws NoSuchElementException* 如果链表为空*/public E removeFirst() {// 获取首结点引用final NodeE f first;// 如果首结点为空则抛出无该元素异常if (f null)throw new NoSuchElementException();// 删除首结点返回存储的元素return unlinkFirst(f);}/*** 删除尾结点返回存储的元素* * return 尾结点存储的元素* throws NoSuchElementException* 如果链表为空*/public E removeLast() {// 获取尾结点引用final NodeE l last;// 如果尾结点为空则抛出无该元素异常if (l null)throw new NoSuchElementException();// 删除尾结点返回存储的元素return unlinkLast(l);}/*** 头部插入指定元素* * param e* 要添加的元素*/public void addFirst(E e) {// 通过头插法来插入指定元素linkFirst(e);}/*** 尾部插入指定元素该方法等价于add()* * param e* the element to add*/public void addLast(E e) {linkLast(e);}/*** 判断是否包含指定元素* * param o* 判断链表是否包含的元素* return {code true} 如果链表包含指定的元素*/public boolean contains(Object o) {// 返回指定元素的索引位置不存在就返回-1然后比较返回bool值return indexOf(o) ! -1;}/*** 获取元素数量* * return 元素数量*/public int size() {return size;}/*** 插入指定元素返回操作结果,默认添加到末尾作为最后一个元素* * param e* 要添加到此链表中的元素* return {code true} (as specified by {link Collection#add})*/public boolean add(E e) {// 通过尾插法来插入指定元素linkLast(e);return true;}/*** 删除指定元素默认从first节点开始删除第一次出现的那个元素* * param o* 要从该列表中删除的元素如果存在* return {code true} 如果这个列表包含指定的元素*/public boolean remove(Object o) {// 会根据是否为null分开处理。若值不是null会用到对象的equals()方法if (o null) {// 遍历链表查找到指定元素后删除该结点返回truefor (NodeE x first; x ! null; x x.next) {if (x.item null) {unlink(x);return true;}}} else {for (NodeE x first; x ! null; x x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}// 查找失败return false;}/*** 将集合插入到链表尾部* * param c* 包含要添加到此链表中的元素的集合* return {code true} 如果该链表因添加而改变* throws NullPointerException* 如果指定的集合是空的*/public boolean addAll(Collection? extends E c) {return addAll(size, c);}/*** 将集合从指定位置开始插入* * param index* 在哪个索引处前插入指定集合中的第一个元素* param c* 包含要添加到此链表中的元素的集合* return {code true} 如果该链表因添加而改变* throws IndexOutOfBoundsException* {inheritDoc}* throws NullPointerException* 如果指定的集合是空的*/public boolean addAll(int index, Collection? extends E c) {// 检查索引是否正确0indexsizecheckPositionIndex(index);// 得到元素数组Object[] a c.toArray();// 得到元素个数int numNew a.length;// 没有元素返回falseif (numNew 0)return false;// succ指向当前需要插入节点的位置pred指向其前一个节点NodeE pred, succ;// 末尾开始添加当前节点后一个节点为null前一个节点为尾节点if (index size) {succ null;pred last;} else { //当前位置的节点为指定位置的节点前一个节点为要添加的节点的前一个节点succ node(index);pred succ.prev;}// 遍历数组并添加到列表中for (Object o : a) {SuppressWarnings(unchecked) E e (E) o;// “封装”一个新节点NodeE newNode new Node(pred, e, null);// 原链表为null新插入的节点作为链表首节点if (pred null)first newNode;elsepred.next newNode; // 存在前节点前节点向后指向新加的节点pred newNode; // pred指针向后移动}// 从最后开始添加则新节点成为尾节点if (succ null) {last pred;} else {pred.next succ; // 新节点向后指向之前得到的后续第一个节点succ.prev pred; // 后续的第一个节点也应改为向前指向最后一个添加的节点}size numNew;modCount;return true;}/*** 删除所有元素*/public void clear() {// 遍历链表删除所有结点,方便gc回收垃圾for (NodeE x first; x ! null; ) {NodeE next x.next;x.item null;x.next null;x.prev null;x next;}// 首尾结点置空first last null;// 元素数量置0size 0;modCount;}// 位置访问操作/*** 获取指定位置的元素* * param index* 要返回的元素的索引* return 该链表中指定位置的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E get(int index) {// 判断指定位置是否合法checkElementIndex(index);// 返回指定位置的元素return node(index).item;}/*** 修改指定位置的元素返回之前元素* * param index* 要替换的元素的索引* param element* 要存储在指定位置的元素* return 之前在指定位置的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E set(int index, E element) {// 判断指定位置是否合法checkElementIndex(index);// 获取指定位置的结点NodeE x node(index);// 获取该结点存储的元素E oldVal x.item;// 修改该结点存储的元素x.item element;// 返回该结点存储的之前的元素return oldVal;}/*** 在指定位置前插入指定元素* 头插法* param index* 指定元素将被插入的索引* param element* 要插入的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public void add(int index, E element) {// 判断指定位置是否合法checkPositionIndex(index);// 如果指定位置在尾部则通过尾插法来插入指定元素if (index size)linkLast(element);else // 如果指定位置不是尾部则添加到指定位置前linkBefore(element, node(index));}/*** 删除指定位置的元素返回之前元素* * param index* 要删除的元素的索引* return 之前在指定位置的元素* throws IndexOutOfBoundsException* {inheritDoc}*/public E remove(int index) {// 判断指定位置是否合法checkElementIndex(index);// 删除指定位置的结点返回之前元素return unlink(node(index));}/*** 判断指定位置是否合法*/private boolean isElementIndex(int index) {return index 0 index size;}/*** 判断迭代器遍历时或插入元素时指定位置是否合法*/private boolean isPositionIndex(int index) {return index 0 index size;}/*** 获取越界异常信息*/private String outOfBoundsMsg(int index) {return Index: index , Size: size;}/*** 判断指定位置是否合法* * param index*/private void checkElementIndex(int index) {if (!isElementIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 判断指定位置是否合法* * param index*/private void checkPositionIndex(int index) {if (!isPositionIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 获取指定下标的结点*/NodeE node(int index) {// 如果指定下标一半元素数量则从首结点开始遍历// 否则从尾结点开始遍历if (index (size 1)) {NodeE x first;for (int i 0; i index; i)x x.next;return x;} else {NodeE x last;for (int i size - 1; i index; i--)x x.prev;return x;}}// 查询操作/*** 获取首次出现指定元素的位置 -1表示不存在* 同样是根据是否为null进行区分* param o* 要查找的元素* return the index of the first occurrence of the specified element in* this list, or -1 if this list does not contain the element*/public int indexOf(Object o) {int index 0;if (o null) {// 遍历链表顺序查找指定元素for (NodeE x first; x ! null; x x.next) {if (x.item null)return index;index;}} else {for (NodeE x first; x ! null; x x.next) {if (o.equals(x.item))return index;index;}}return -1;}/*** 获取逆序下首次出现指定元素的位置 -1表示不存在* * param o* 要查找的元素* return the index of the last occurrence of the specified element in this* list, or -1 if this list does not contain the element*/public int lastIndexOf(Object o) {int index size;if (o null) {// 遍历链表逆序查找指定元素for (NodeE x last; x ! null; x x.prev) {index--;if (x.item null)return index;}} else {for (NodeE x last; x ! null; x x.prev) {index--;if (o.equals(x.item))return index;}}return -1;}// 队列操作/*** 出队从前端获得第一个元素不存在会返回null不会删除元素节点 获取首元素* * return the head of this list, or {code null} 如果链表为空* since 1.5*/public E peek() {final NodeE f first;// 如果首结点为空则返回null// 否则返回首结点存储的元素return (f null) ? null : f.item;}/*** 出队从前端不删除元素若为null会抛出异常而不是返回null 获取首元素* * return the head of this list* throws NoSuchElementException* 如果链表为空* since 1.5*/public E element() {// 返回首结点存储的元素return getFirst();}/*** 出队从前端如果不存在会返回null存在的话会返回值并移除这个元素节点 获取并删除首元素* * return the head of this list, or {code null} 如果链表为空* since 1.5*/public E poll() {// 获取首结点引用final NodeE f first;// 如果首结点为空则返回null// 否则删除首结点返回首结点存储的元素return (f null) ? null : unlinkFirst(f);}/*** 出队从前端如果不存在会抛出异常而不是返回null存在的话会返回值并移除这个元素节点 获取并删除首元素* * return the head of this list* throws NoSuchElementException* 如果链表为空* since 1.5*/public E remove() {// 删除首结点返回首结点存储的元素return removeFirst();}/*** 入队从后端始终返回true* * 链表不会溢出* param e* the element to add* return {code true} (as specified by {link Queue#offer})* since 1.5*/public boolean offer(E e) {// 通过尾插法插入指定元素返回操作结果return add(e);}// 双端队列操作/*** 入队从前端始终返回true* * param e* 要插入的元素* return {code true} (as specified by {link Deque#offerFirst})* since 1.6*/public boolean offerFirst(E e) {// 通过头插法来插入指定元素addFirst(e);return true;}/*** 入队从后端始终返回true* * param e* 要插入的元素* return {code true} (as specified by {link Deque#offerLast})* since 1.6*/public boolean offerLast(E e) {// 通过尾插法来插入指定元素addLast(e);return true;}/*** 出队从前端获得第一个元素不存在会返回null不会删除元素节点* * return the first element of this list, or {code null} 如果链表为空* since 1.6*/public E peekFirst() {// 获取首结点引用final NodeE f first;// 如果首结点为空则返回null// 否则返回首结点存储的元素return (f null) ? null : f.item;}/*** 出队从后端获得最后一个元素不存在会返回null不会删除元素节点* * return the last element of this list, or {code null} 如果链表为空* since 1.6*/public E peekLast() {// 获取尾结点引用final NodeE l last;// 如果尾结点为空则返回null// 否则返回尾结点存储的元素return (l null) ? null : l.item;}/*** 出队从前端获得第一个元素不存在会返回null会删除元素节点* * return the first element of this list, or {code null} if this list is* empty* since 1.6*/public E pollFirst() {// 获取首结点引用final NodeE f first;// 如果首结点为空则返回null// 否则删除首结点返回首结点存储的元素return (f null) ? null : unlinkFirst(f);}/*** 出队从后端获得最后一个元素不存在会返回null会删除元素节点* * return the last element of this list, or {code null} if this list is* empty* since 1.6*/public E pollLast() {// 获取尾结点引用final NodeE l last;// 如果尾结点为空则返回null// 否则删除尾结点返回尾结点存储的元素return (l null) ? null : unlinkLast(l);}/*** 入栈从前面添加* * param e* the element to push* since 1.6*/public void push(E e) {// 通过头插法来插入指定元素addFirst(e);}/*** 出栈返回栈顶元素从前面移除会删除* * return the element at the front of this list (which is the top of the* stack represented by this list)* throws NoSuchElementException* 如果链表为空* since 1.6*/public E pop() {// 删除首结点返回首结点存储的元素return removeFirst();}/*** 删除顺序下首次出现的指定元素返回操作结果* * param o* 要从该列表中删除的元素如果存在* return {code true} 如果链表包含指定的元素* since 1.6*/public boolean removeFirstOccurrence(Object o) {// 删除顺序下首次出现的指定元素对应的结点返回操作结果return remove(o);}/*** 删除逆序下首次出现的指定元素返回操作结果* * param o* 要从该列表中删除的元素如果存在* return {code true} 如果链表包含指定的元素* since 1.6*/public boolean removeLastOccurrence(Object o) {// 由于LinkedList中允许存放null因此下面通过两种情况来分别处理if (o null) {// 遍历链表从尾结点开始查找指定元素// 如果查找成功删除该结点返回truefor (NodeE x last; x ! null; x x.prev) {if (x.item null) {unlink(x);return true;}}} else {for (NodeE x last; x ! null; x x.prev) {if (o.equals(x.item)) {unlink(x);return true;}}}// 查找失败return false;}/*** Returns a list-iterator of the elements in this list (in proper* sequence), starting at the specified position in the list. Obeys the* general contract of {code List.listIterator(int)}.* p* p* The list-iterator is ifail-fast/i: if the list is structurally* modified at any time after the Iterator is created, in any way except* through the list-iterators own {code remove} or {code add} methods,* the list-iterator will throw a {code ConcurrentModificationException}.* Thus, in the face of concurrent modification, the iterator fails quickly* and cleanly, rather than risking arbitrary, non-deterministic behavior at* an undetermined time in the future.* * param index* index of the first element to be returned from the* list-iterator (by a call to {code next})* return a ListIterator of the elements in this list (in proper sequence),* starting at the specified position in the list* throws IndexOutOfBoundsException* {inheritDoc}* see List#listIterator(int)*/public ListIteratorE listIterator(int index) {checkPositionIndex(index);return new ListItr(index);}private class ListItr implements ListIteratorE {private NodeE lastReturned;private NodeE next;private int nextIndex;private int expectedModCount modCount;ListItr(int index) {// assert isPositionIndex(index);next (index size) ? null : node(index);nextIndex index;}public boolean hasNext() {return nextIndex size;}public E next() {checkForComodification();if (!hasNext())throw new NoSuchElementException();lastReturned next;next next.next;nextIndex;return lastReturned.item;}public boolean hasPrevious() {return nextIndex 0;}public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned next (next null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned null)throw new IllegalStateException();NodeE lastNext lastReturned.next;unlink(lastReturned);if (next lastReturned)next lastNext;elsenextIndex--;lastReturned null;expectedModCount;}public void set(E e) {if (lastReturned null)throw new IllegalStateException();checkForComodification();lastReturned.item e;}public void add(E e) {checkForComodification();lastReturned null;if (next null)linkLast(e);elselinkBefore(e, next);nextIndex;expectedModCount;}public void forEachRemaining(Consumer? super E action) {Objects.requireNonNull(action);while (modCount expectedModCount nextIndex size) {action.accept(next.item);lastReturned next;next next.next;nextIndex;}checkForComodification();}final void checkForComodification() {if (modCount ! expectedModCount)throw new ConcurrentModificationException();}}/*** 节点的数据结构包含前后节点的引用和当前节点* * param E*/private static class NodeE {// 存储的元素E item;// 后继结点NodeE next;// 前驱结点NodeE prev;// 前驱结点、存储的元素和后继结点作为参数的构造方法Node(NodeE prev, E element, NodeE next) {this.item element;this.next next;this.prev prev;}}/*** 返回迭代器* * since 1.6*/public IteratorE descendingIterator() {return new DescendingIterator();}/*** 因为采用链表实现所以迭代器很简单*/private class DescendingIterator implements IteratorE {private final ListItr itr new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}/*** 父类克隆方法*/SuppressWarnings(unchecked)private LinkedListE superClone() {try {return (LinkedListE) super.clone();} catch (CloneNotSupportedException e) {throw new InternalError(e);}}/*** 克隆浅拷贝* * 浅拷贝时若存储的是对象的引用拷贝时对象本身的改变将表现到副本中而深拷贝不会。* return a shallow copy of this {code LinkedList} instance*/public Object clone() {LinkedListE clone superClone();// 链表初始化clone.first clone.last null;clone.size 0;clone.modCount 0;// 插入结点for (NodeE x first; x ! null; x x.next)clone.add(x.item);// 返回克隆后的对象引用return clone;}/*** 返回新的数组数组含有列表中所有元素*/public Object[] toArray() {Object[] result new Object[size];int i 0;for (NodeE x first; x ! null; x x.next)result[i] x.item;return result;}/*** Returns an array containing all of the elements in this list in proper* sequence (from first to last element); the runtime type of the returned* array is that of the specified array. If the list fits in the specified* array, it is returned therein. Otherwise, a new array is allocated with* the runtime type of the specified array and the size of this list.* p* p* If the list fits in the specified array with room to spare (i.e., the* array has more elements than the list), the element in the array* immediately following the end of the list is set to {code null}. (This* is useful in determining the length of the list ionly/i if the* caller knows that the list does not contain any null elements.)* p* p* Like the {link #toArray()} method, this method acts as bridge between* array-based and collection-based APIs. Further, this method allows* precise control over the runtime type of the output array, and may, under* certain circumstances, be used to save allocation costs.* p* p* Suppose {code x} is a list known to contain only strings. The following* code can be used to dump the list into a newly allocated array of* {code String}:* p* * pre* String[] y x.toArray(new String[0]);* /pre* * p* Note that {code toArray(new Object[0])} is identical in function to* {code toArray()}.* * param a* the array into which the elements of the list are to be* stored, if it is big enough; otherwise, a new array of the* same runtime type is allocated for this purpose.* 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)a (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);int i 0;Object[] result a;for (NodeE x first; x ! null; x x.next)result[i] x.item;if (a.length size)a[size] null;return a;}private static final long serialVersionUID 876323262645176354L;/*** 序列化*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {// 默认序列化s.defaultWriteObject();// 写入元素数量s.writeInt(size);// 遍历链表写入所有元素for (NodeE x first; x ! null; x x.next)s.writeObject(x.item);}/*** 反序列化*/SuppressWarnings(unchecked)private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {// 默认反序列化s.defaultReadObject();// 读取元素数量int size s.readInt();// 遍历链表读取所有元素并尾部插入for (int i 0; i size; i)linkLast((E) s.readObject());}/*** Creates a ema hrefSpliterator.html#bindinglate-binding/a/em* and emfail-fast/em {link Spliterator} over the elements in this* list.* p* p* The {code Spliterator} reports {link Spliterator#SIZED} and* {link Spliterator#ORDERED}. Overriding implementations should document* the reporting of additional characteristic values.* * return a {code Spliterator} over the elements in this list* implNote The {code Spliterator} additionally reports* {link Spliterator#SUBSIZED} and implements {code trySplit} to* permit limited parallelism..* since 1.8*/Overridepublic SpliteratorE spliterator() {return new LLSpliteratorE(this, -1, 0);}/*** A customized variant of Spliterators.IteratorSpliterator*/static final class LLSpliteratorE implements SpliteratorE {static final int BATCH_UNIT 1 10; // batch array size incrementstatic final int MAX_BATCH 1 25; // max batch array size;final LinkedListE list; // null OK unless traversedNodeE current; // current node; null until initializedint est; // size estimate; -1 until first neededint expectedModCount; // initialized when est setint batch; // batch size for splitsLLSpliterator(LinkedListE list, int est, int expectedModCount) {this.list list;this.est est;this.expectedModCount expectedModCount;}final int getEst() {int s; // force initializationfinal LinkedListE lst;if ((s est) 0) {if ((lst list) null)s est 0;else {expectedModCount lst.modCount;current lst.first;s est lst.size;}}return s;}public long estimateSize() {return (long) getEst();}public SpliteratorE trySplit() {NodeE p;int s getEst();if (s 1 (p current) ! null) {int n batch BATCH_UNIT;if (n s)n s;if (n MAX_BATCH)n MAX_BATCH;Object[] a new Object[n];int j 0;do {a[j] p.item;} while ((p p.next) ! null j n);current p;batch j;est s - j;return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);}return null;}public void forEachRemaining(Consumer? super E action) {NodeE p;int n;if (action null) throw new NullPointerException();if ((n getEst()) 0 (p current) ! null) {current null;est 0;do {E e p.item;p p.next;action.accept(e);} while (p ! null --n 0);}if (list.modCount ! expectedModCount)throw new ConcurrentModificationException();}public boolean tryAdvance(Consumer? super E action) {NodeE p;if (action null) throw new NullPointerException();if (getEst() 0 (p current) ! null) {--est;E e p.item;current p.next;action.accept(e);if (list.modCount ! expectedModCount)throw new ConcurrentModificationException();return true;}return false;}public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}}} Vector 基于synchronized实现的线程安全的ArrayList但在插入元素时容量扩充的机制和ArrayList稍有不同并可通过传入capacityIncrement来控制容量的扩充。 成员变量 protected Object[] elementData; protected int elementCount; protected int capacityIncrement; 构造方法 public Vector(int initialCapacity) {this(initialCapacity, 0); } public Vector() {this(10); } public Vector(int initialCapacity, int capacityIncrement) {super();if (initialCapacity 0)throw new IllegalArgumentException(Illegal Capacity: initialCapacity);this.elementData new Object[initialCapacity];this.capacityIncrement capacityIncrement; } 添加 public synchronized boolean add(E e) {modCount;ensureCapacityHelper(elementCount 1);elementData[elementCount] e;return true; } 删除 public boolean remove(Object o) {return removeElement(o); }public synchronized boolean removeElement(Object obj) {modCount;int i indexOf(obj);if (i 0) {removeElementAt(i);return true;}return false; } 扩容 private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity elementData.length;int newCapacity oldCapacity ((capacityIncrement 0) ?capacityIncrement : oldCapacity);if (newCapacity - minCapacity 0)newCapacity minCapacity;if (newCapacity - MAX_ARRAY_SIZE 0)newCapacity hugeCapacity(minCapacity);elementData Arrays.copyOf(elementData, newCapacity); } 获取 public synchronized E get(int index) {if (index elementCount)throw new ArrayIndexOutOfBoundsException(index);return elementData(index); } 更新 public synchronized E set(int index, E element) {if (index elementCount)throw new ArrayIndexOutOfBoundsException(index);E oldValue elementData(index);elementData[index] element;return oldValue; } 包含 public boolean contains(Object o) {return indexOf(o, 0) 0; }public synchronized int indexOf(Object o, int index) {if (o null) {for (int i index ; i elementCount ; i)if (elementData[i]null)return i;} else {for (int i index ; i elementCount ; i)if (o.equals(elementData[i]))return i;}return -1; } CopyOnWriteArrayList 是一个线程安全、并且在读操作时无锁的ArrayList。 很多时候我们的系统应对的都是读多写少的并发场景。CopyOnWriteArrayList容器允许并发读读操作是无锁的性能较高。至于写操作比如向容器中添加一个元素则首先将当前容器复制一份然后在新副本上执行写操作结束之后再将原容器的引用指向新容器。 优点 1采用读写分离方式读的效率非常高 2CopyOnWriteArrayList的迭代器是基于创建时的数据快照的故数组的增删改不会影响到迭代器 缺点 1内存占用高每次执行写操作都要将原容器拷贝一份数据量大时对内存压力较大可能会引起频繁GC 2只能保证数据的最终一致性不能保证数据的实时一致性。写和读分别作用在新老不同容器上在写操作执行过程中读不会阻塞但读取到的却是老容器的数据。 成员变量 /** The lock protecting all mutators */final transient ReentrantLock lock new ReentrantLock();/** The array, accessed only via getArray/setArray. */private transient volatile Object[] array; 构造方法 public CopyOnWriteArrayList() {setArray(new Object[0]); }final void setArray(Object[] a) {array a; } 添加有锁锁内重新创建数组 final Object[] getArray() {return array;}public boolean add(E e) {final ReentrantLock lock this.lock;lock.lock();try {Object[] elements getArray();int len elements.length;Object[] newElements Arrays.copyOf(elements, len 1);newElements[len] e;setArray(newElements);return true;} finally {lock.unlock();} } 存在则添加有锁锁内重新创建数组 先保存一份数组snapshot如果snapshot中存在则直接返回。 如果不存在那么加锁获取当前数组current比较snapshot与current遍历它们共同长度内的元素如果发现current中某一个元素等于e那么直接返回当然current与snapshot相同就不必看了 之后再遍历current单独的部分如果发现current中某一个元素等于e那么直接返回 此时可以去创建一个长度1的新数组将e加入。 public boolean addIfAbsent(E e) {Object[] snapshot getArray();return indexOf(e, snapshot, 0, snapshot.length) 0 ? false :addIfAbsent(e, snapshot); }private boolean addIfAbsent(E e, Object[] snapshot) {final ReentrantLock lock this.lock;lock.lock();try {Object[] current getArray();int len current.length;if (snapshot ! current) {// Optimize for lost race to another addXXX operationint common Math.min(snapshot.length, len);for (int i 0; i common; i)//如果snapshot与current元素不同但current与e相同那么直接返回扫描0到commonif (current[i] ! snapshot[i] eq(e, current[i]))return false;// 如果current中存在e那么直接返回扫描commen到lenif (indexOf(e, current, common, len) 0)return false;}Object[] newElements Arrays.copyOf(current, len 1);newElements[len] e;setArray(newElements);return true;} finally {lock.unlock();} } 删除有锁锁内重新创建数组 public E remove(int index) {final ReentrantLock lock this.lock;lock.lock();try {Object[] elements getArray();int len elements.length;E oldValue get(elements, index);int numMoved len - index - 1;if (numMoved 0)setArray(Arrays.copyOf(elements, len - 1));else {Object[] newElements new Object[len - 1];System.arraycopy(elements, 0, newElements, 0, index);System.arraycopy(elements, index 1, newElements, index,numMoved);setArray(newElements);}return oldValue;} finally {lock.unlock();} } 获取无锁 public E get(int index) {return get(getArray(), index); }private E get(Object[] a, int index) {return (E) a[index]; } 更新有锁锁内重新创建数组 public E set(int index, E element) {final ReentrantLock lock this.lock;lock.lock();try {Object[] elements getArray();E oldValue get(elements, index);if (oldValue ! element) {int len elements.length;Object[] newElements Arrays.copyOf(elements, len);newElements[index] element;setArray(newElements);} else {// 为了保持“volatile”的语义任何一个读操作都应该是一个写操作的结果也就是读操作看到的数据一定是某个写操作的结果尽管写操作没有改变数据本身。所以这里即使不设置也没有问题仅仅是为了一个语义上的补充就如源码中的注释所言// Not quite a no-op; ensures volatile write semanticssetArray(elements);}return oldValue;} finally {lock.unlock();} } 包含无锁 public boolean contains(Object o) {Object[] elements getArray();return indexOf(o, elements, 0, elements.length) 0; }private static int indexOf(Object o, Object[] elements,int index, int fence) {if (o null) {for (int i index; i fence; i)if (elements[i] null)return i;} else {for (int i index; i fence; i)if (o.equals(elements[i]))return i;}return -1; } List实现类之间的区别 (1) 对于需要快速插入删除元素应该使用LinkedList。 (2) 对于需要快速随机访问元素应该使用ArrayList。 (3) 对于“单线程环境” 或者 “多线程环境但List仅仅只会被单个线程操作”此时应该使用非同步的类(如ArrayList)。 对于“多线程环境且List可能同时被多个线程操作”此时应该使用同步的类(如Vector、CopyOnWriteArrayList)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/915524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

象山县城乡建设局网站网站主页图片怎么换

🔆 文章首发于我的个人博客:欢迎大佬们来逛逛 数学建模:多目标优化算法 多目标优化 分别求权重方法 算法流程: 两个目标权重求和,化为单目标函数,然后求解最优值 min ⁡ x ∑ i 1 m w i F i ( x ) s.…

OpenCV:人脸识别实战,3 种算法(LBPH/EigenFaces/FisherFaces)代码详解 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:Playwright录制时的高亮实现机制分析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

什么是文件外发审批?主要有哪几种关键流程?

文件外发审批是企业进行外部文档传输时不可或缺的一部分。它涵盖了从申请发起到文档送达后反馈的一系列环节。在申请阶段,员工需要利用Ftrans B2B企业间文件安全交换系统,准确填写申请信息以确保透明度和合规性。随后…

VPX处理板设计原理图:9-基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡 C6678板卡, XC7VX690T板卡, VPX处理板

基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡 一、概述本板卡基于标准6U VPX 架构,为通用高性能信号处理平台,系我公司自主研发。板卡采用一片TI DSP TMS320C6678和一片Xilinx公司Virtex 7系列的FPGA XC7V6…

Python入门—Mac如何搭建Python开发环境?

Python入门—Mac如何搭建Python开发环境?Python入门—Mac如何搭建Python开发环境?编程玉子 ​关注她14 人赞同了该文章随着Numpy、Scipy、Matplotlib和Pandas等众多程序库的开发,python在数据分析、数据挖掘、海量数…

织梦做网站简单吗高端网站建设公司排名

1.概述 封装(Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。 要访问该类的代码和数据,必须通过严格的接口控制…

VitePress 添加友链界面

效果预览友链数据存储 友链数据通常是经常需要添加和修改的,所以我们不能直接写死到页面上。这里我们单独提一个文件去存储友链数据,并且友链数据的格式基本也是类似的。 新建 docs/pages/links.md 文件,内容如下:…

跨网文件摆渡软件:企业数据安全高效传输的关键解决方案!

在数字化时代,企业为保障核心数据安全,普遍采用网络隔离策略,将内网与外网、研发网与办公网等不同网络环境分隔开来。然而,业务协同中跨网文件传输的需求始终存在,跨网文件摆渡软件应运而生。这类软件是专门用于在…

洛谷题单指南-进阶数论-P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

原题链接:https://www.luogu.com.cn/problem/P1495 题意解读:求方程组x ≡ bi (mod ai), i∈[1,n]的最小正整数解,所有的ai互质。 解题思路: 1、中国剩余定理 设方程组为(a1,a2,a3互质):x ≡ b1 (mod a1) x ≡…

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用…

c语言之自定义memcpy

void *Memcpy(void *dest, const void *src, size_t count) { cout<<"sizeof(dest)是:"<<sizeof(dest)<<endl;int bytelen=count/sizeof(dest); /*按CPU位宽拷贝*/int slice=count%si…

国产芯片处理板卡:7-基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡

基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡一、板卡概述本板卡系我公司自主研发,基于6U CPCI的通用高性能信号处理平台。板卡采用一片国产8核DSP FT-C6678和一片国产FPGA JFM7K325T-2FFG900作为主处理器。为您…

一文详解纷享销客CRM Agent平台3大核心能力(附应用场景与案例)

AI 技术加速渗透业务场景,智能体(Agent)已成为企业提效增长的关键工具 —— 它可助力销售快速掌握客户经营情况、辅助运营规避数据操作差错、帮助新人高效获取业务知识,在营销、销售、服务全链路实现 “数据洞察 -…

php网站开发实训总结东莞网络营销全网推广

简介&#xff1a;企业想要拥有领先的数据分析能力&#xff0c;自研往往需要投入巨大的人力和财力。 Quick BI作为唯一一个连续两年入选Gartner魔力象限的中国BI产品&#xff0c;具备强大的全链路开放集成能力&#xff0c;可以轻松的与企业原有系统匹配融合&#xff0c;帮助企业…

QOJ #5076. Prof. Pang and Ants 题解

Description 在庞教授的大房子边上,有一群包含 \(m\) 只蚂蚁的蚁群,居住在有 \(n\) 个洞口的洞穴里。 它们会外出寻找食物。食物在庞教授的大冰箱里,蚂蚁们试图从里面偷出食物来。 特别的, 一只蚂蚁需要 \(1\) 秒从…

微信小程序(uniapp)PDF预览完整实现方案

微信小程序(uniapp)PDF预览完整实现方案Posted on 2025-09-24 09:36 且行且思 阅读(0) 评论(0) 收藏 举报在微信小程序开发中,PDF文件预览是常见的业务需求。本文将提供一套基于uniapp的完整解决方案,涵盖从后…

发现5个宝藏文件摆渡系统 2025年企业首选的摆渡方案是这个!

文件摆渡系统作为解决网络隔离后业务交互的重要工具,其作用和价值不言而喻。不过对于企业的价值究竟是正面的,还是负面的,这就要看用的什么文件摆渡系统了。本文中我们就介绍5种文件摆渡系统,我们来看看首选的摆渡…

如何打开谷歌网站网站备案网站

文章目录 一、文档转换器 & 文本拆分器文本拆分器 二、开始使用文本拆分器三、按字符进行拆分四、代码分割 (Split code)1、PythonTextSplitter2、JS3、Markdown4、Latex5、HTML6、Solidity 五、MarkdownHeaderTextSplitter1、动机2、Use case 六、递归按字符分割七、按tok…