13)从头开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1。
/**
* 从头开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1
*/
@Override
public int indexOf(Object o) { /**
* 返回第一个匹配元素的索引
*/
if (o == null) { for (int i = 0; i < this.size; i++) { if (this.elementData[i]==null) { return i;
}
}
} else { for (int i = 0; i < this.size; i++) { if (o.equals(this.elementData[i])) { return i;
}
}
} return -1;
}14)从尾部开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1。
/**
* 从尾部开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1
*/
@Override
public int lastIndexOf(Object o) { /**
* 返回第一个匹配元素的索引
*/
if (o == null) { for (int i = this.size-1; i >= 0; i--) { if (this.elementData[i]==null) { return i;
}
}
} else { for (int i = this.size-1; i >= 0; i--) { if (o.equals(this.elementData[i])) { return i;
}
}
} return -1;
}15)ArrayList 中是否包含和目标元素相等的元素,如果包含,则返回 true;否则返回 false。
/**
* 从头开始遍历,并通过 {@link Object#equals(Object)} 方法获取相等元素的索引
*/
@Override
public boolean contains(Object o) { return this.indexOf(o) >= 0;
}16)ArrayList 中当前元素的个数
/**
* 当前元素个数
* created by ZXD at 15 Jul 2018 T 11:25:21
* @return
*/
@Override
public int size() { return this.size;
}17)ArrayList 是否为空
/**
* 是否为空
* created by ZXD at 15 Jul 2018 T 11:25:48
* @return
*/
@Override
public boolean isEmpty() { return this.size == 0;
}18)将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用,适合于静态 ArrayList 实例。
/**
* 将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用。
*/
public void trimToSize() { // 结构修改计数器
modCount++; /**
* 当元素个数小于对象数组长度时,缩小其容量为元素个数,降低 ArrayList 的内存占用。
*/
if (this.size < this.elementData.length) { this.elementData = this.size == 0
? ArrayList.EMPTY_ELEMENTDATA
: Arrays.copyOf(this.elementData, this.size);
}
}19)如果需要,则增加 ArrayList 的容量以满足最少能容纳 minCapacity 个元素。
/**
* 增加 ArrayList 的容量以满足最少能容纳 minCapacity 个元素
*/
public void ensureCapacity(int minCapacity) { /**
* 预期容量大于可用容量时执行扩容操作
*/
if (minCapacity > this.elementData.length
&& !(this.elementData == ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= ArrayList.DEFAULT_CAPACITY)) {
modCount++; this.grow(minCapacity);
}
}20)将 ArrayList 转换为指定类型的对象数组,包含所有元素。
@Override
@SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { /**
* 形参数组的长度小于 ArrayList 的 size,则默认复制 ArrayList 的所有元素,
* 长度为 ArrayList 的 size。
*/
if (a.length < this.size) { return (T[]) Arrays.copyOf(this.elementData, this.size, a.getClass());
}
System.arraycopy(this.elementData, 0, a, 0, this.size); /**
* 复制 ArrayList 的所有元素,并将索引为 size 的元素设置为 null,返回新数组
*/
if (a.length > this.size) {
a[this.size] = null;
} return a;
}21)将 ArrayList 实例转换为 Object 对象数组
/**
* 返回包含 ArrayList 所有元素的对象数组
*/
@Override
public Object[] toArray() { // 拷贝出 ArrayList 中存储在底层对象数组中的所有元素
return Arrays.copyOf(this.elementData, this.size);
}22)使用函数式接口顺序消费 ArrayList 中的每个元素,出现并发修改时,之前消费的元素不能回滚
/**
* 顺序消费 ArrayList 中的每个元素
*/
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action); // 缓存并发修改计数值
final int expectedModCount = modCount; // 读取底层对象数组
final Object[] es = this.elementData; // 读取元素个数
final int size = this.size; // 遍历每个元素并调用函数式接口进行消费
for (int i = 0; modCount == expectedModCount && i < size; i++) {
action.accept(ArrayList.elementAt(es, i));
} if (modCount != expectedModCount) { throw new ConcurrentModificationException();
}
}23)移除 ArrayList 中满足指定函数式断言的所有元素
/**
* 移除 ArrayList 中满足指定函数式断言的所有元素
*/
@Override
public boolean removeIf(Predicate<? super E> filter) { return this.removeIf(filter, 0, this.size);
} /**
* Removes all elements satisfying the given predicate, from index
* i (inclusive) to index end (exclusive).
* 【移除所有满足指定断言的元素,包括起始索引,不包括结束索引】
*/
boolean removeIf(Predicate<? super E> filter, int i, final int end) {
Objects.requireNonNull(filter); int expectedModCount = modCount; final Object[] es = this.elementData; /**
* 从头开始略过不满足断言的元素,找到第一个需要移除的元素索引
*/
for (; i < end && !filter.test(ArrayList.elementAt(es, i)); i++) {
;
} // Tolerate predicates that reentrantly access the collection for
// read (but writers still get CME), so traverse once to find
// elements to delete, a second pass to physically expunge.
if (i < end) { final int beg = i; final long[] deathRow = ArrayList.nBits(end - beg);
deathRow[0] = 1L; // set bit 0
for (i = beg + 1; i < end; i++) { if (filter.test(ArrayList.elementAt(es, i))) {
ArrayList.setBit(deathRow, i - beg);
}
} if (modCount != expectedModCount) { throw new ConcurrentModificationException();
}
expectedModCount++;
modCount++; int w = beg; for (i = beg; i < end; i++) { if (ArrayList.isClear(deathRow, i - beg)) {
es[w++] = es[i];
}
} this.shiftTailOverGap(es, w, end); return true;
} else { if (modCount != expectedModCount) { throw new ConcurrentModificationException();
} return false;
}
}24)将 ArrayList 中的所有元素替换为通过二元函数式接口变换后的值,元素类型保持不变。
/**
* UnaryOperator 接受类型为 E 的参数并返回类型为 E 的对象
*/
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator); final int expectedModCount = modCount; final Object[] es = this.elementData; final int size = this.size; for (int i = 0; modCount == expectedModCount && i < size; i++) { // 遍历并替换 ArrayList 中的每个元素
es[i] = operator.apply(ArrayList.elementAt(es, i));
} if (modCount != expectedModCount) { throw new ConcurrentModificationException();
}
modCount++;
}25)通过指定的比较器对 ArrayList 中的元素执行排序
/**
* 对 ArrayList 进行排序
*/
@Override
@SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; // 对对象数组内指定范围的元素执行排序
Arrays.sort((E[]) this.elementData, 0, this.size, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException();
}
modCount++;
}26)返回 ArrayList 的顺序迭代器
/**
* 返回 ArrayList 的顺序迭代器
*/
@Override
public Iterator<E> iterator() { return new Itr();
} /**
* An optimized version of AbstractList.Itr
* 只能往后遍历,支持移除元素
*/
private class Itr implements Iterator<E> { int cursor; // 下一个返回元素的索引,从 0 开始
int lastRet = -1; // 最近一个返回元素的索引
int expectedModCount = ArrayList.this.modCount; // fast-fail 机制的计数器
Itr() {} /**
* 是否还有下一个元素
* created by ZXD at 15 Jul 2018 T 11:39:55
* @return
*/
@Override
public boolean hasNext() { return this.cursor != ArrayList.this.size;
} /**
* 获取下一个元素
* created by ZXD at 15 Jul 2018 T 11:40:12
* @return
*/
@Override
@SuppressWarnings("unchecked") public E next() { /**
* 并发修改校验,创建迭代器时会获取外部修改计数器值并将其缓存,
* 通过比较缓存值和外部计数器值来判断是否发生并发结构修改。
*/
this.checkForComodification(); // 获取下一个元素的索引
final int i = this.cursor; // 元素已经全部遍历完成,并发遍历时其中有线程删除了元素时可能出现
if (i >= ArrayList.this.size) { throw new NoSuchElementException();
} final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException();
} // 递增游标值
this.cursor = i + 1; // 返回目标值
return (E) elementData[this.lastRet = i];
} @Override
public void remove() { if (this.lastRet < 0) { throw new IllegalStateException();
} this.checkForComodification(); try { // 移除 ArrayList 中的元素
ArrayList.this.remove(this.lastRet); // 更新游标值
this.cursor = this.lastRet; // 移除元素时,lastRet 置为 -1
this.lastRet = -1; // 更新内部的并发修改计数值
this.expectedModCount = ArrayList.this.modCount;
} catch (final IndexOutOfBoundsException ex) { throw new ConcurrentModificationException();
}
} /**
* 顺序消费未迭代的所有元素
* created by ZXD at 15 Jul 2018 T 11:44:41
* @param action
*/
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action); final int size = ArrayList.this.size; int i = this.cursor; if (i < size) { final Object[] es = ArrayList.this.elementData; if (i >= es.length) { throw new ConcurrentModificationException();
} // 游标值小于 size 并且未发生并发结构修改
for (; i < size && ArrayList.this.modCount == this.expectedModCount; i++) { // 使用函数式接口消费目标元素
action.accept(ArrayList.elementAt(es, i));
} // update once at end to reduce heap write traffic
// 更新游标值
this.cursor = i; this.lastRet = i - 1; this.checkForComodification();
}
} final void checkForComodification() { /**
* 判断是否存在多线程并发修改 ArrayList 实例
*/
if (ArrayList.this.modCount != this.expectedModCount) { throw new ConcurrentModificationException();
}
}
}27)返回 ArrayList 的列表迭代器
/**
* 返回 ArrayList 的列表迭代器
*/
@Override
public ListIterator<E> listIterator() { return new ListItr(0);
} /**
* An optimized version of AbstractList.ListItr
* 支持向前或向后遍历,支持在迭代过程中增加、移除、修改元素
*/
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) { super();
cursor = index;
} /**
* 是否存在可迭代的前一个元素
* created by ZXD at 15 Jul 2018 T 11:47:17
* @return
*/
@Override
public boolean hasPrevious() { return cursor != 0;
} /**
* 获取下一个迭代元素的索引
* created by ZXD at 15 Jul 2018 T 11:47:45
* @return
*/
@Override
public int nextIndex() { return cursor;
} /**
* 获取前一个迭代元素的索引
* created by ZXD at 15 Jul 2018 T 11:48:02
* @return
*/
@Override
public int previousIndex() { return cursor - 1;
} /**
* 获取前一个迭代元素
* created by ZXD at 15 Jul 2018 T 11:48:20
* @return
*/
@Override
@SuppressWarnings("unchecked") public E previous() {
checkForComodification(); final int i = cursor - 1; if (i < 0) { throw new NoSuchElementException();
} final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException();
} // 更新游标并返回目标元素
cursor = i; return (E) elementData[lastRet = i];
} /**
* 更新最后一次返回的元素
* created by ZXD at 15 Jul 2018 T 11:49:59
* @param e
*/
@Override
public void set(E e) { if (lastRet < 0) { throw new IllegalStateException();
}
checkForComodification(); try {
ArrayList.this.set(lastRet, e);
} catch (final IndexOutOfBoundsException ex) { throw new ConcurrentModificationException();
}
} /**
* 迭代过程中动态将元素插入到下一次迭代的索引处
* created by ZXD at 15 Jul 2018 T 11:50:25
* @param e
*/
@Override
public void add(E e) {
checkForComodification(); try { final int i = cursor;
ArrayList.this.add(i, e); // 更新游标、最后一次返回的元素下标、结构修改计数值
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (final IndexOutOfBoundsException ex) { throw new ConcurrentModificationException();
}
}
}28)清空 ArrayList
/**
* 清空数组元素和 size
*/
@Override
public void clear() {
modCount++; final Object[] es = this.elementData; // 将对象数组前 size 个元素置为 null
for (int to = this.size, i = this.size = 0; i < to; i++) {
es[i] = null;
}
}原文出处:https://www.cnblogs.com/zhuxudong/p/9581072.html
随时随地看视频