标签:现在 bool false advance 初始 inter iter ati 前言
上次看ArrayList底层机制时把ArrayListSpliterator
放了放,现在回过头来具体看看实现。
直接上代码吧!
static final class ArrayListSpliterator<E> implements Spliterator<E> {
//指向当前集合对象
private final ArrayList<E> list;
//当前索引,可能被trySplit和tryAdvance操作修改
private int index;
//结束索引,未使用前为-1,使用后为list的size
private int fence;
//通过与modCount比较来判断集合是否被修改,初始值与modCount相等
private int expectedModCount;
/**
* 初始化参数
* @param list 当前集合
* @param origin 起始索引
* @param fence 结束索引
* @param expectedModCount
*/
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
int expectedModCount) {
this.list = list; // OK if null unless traversed
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
/**
* 获取结束索引
* 初始化expectedModCount与fence参数
* @return 结束索引
*/
private int getFence() { // initialize fence to size on first use
int 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;
}
/**
* 在当前切割迭代器的基础上再次拆分一个新的迭代器
* 若切割迭代器是可以拆分的,会返回新的一个切割迭代器,两个迭代器平分原先迭代器中的元素
* 若切割迭代器无法拆分的话,则返回null
* 拆分后原先迭代器必须修改起始索引,因为它的元素被拆分了(index = mid)
* @return 新的切割迭代器或null
*/
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<E>(list, lo, index = mid,
expectedModCount);
}
/**
* 若存在剩余元素,则对其下一个元素执行指定动作,并返回true
* 若不存在剩余元素,则返回false
* 该方法是对单独元素进行操作
* @param action 若存在剩余元素,执行指定动作
* @return 是否存在剩余元素
*/
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;
}
/**
* 遍历剩余元素,并执行指定动作
* @param action 若存在剩余元素,执行指定动作
*/
public void forEachRemaining(Consumer<? super E> action) {
int i, hi, mc; // hoist accesses and checks from loop
ArrayList<E> lst; Object[] a;
if (action == null)
throw new NullPointerException();
if ((lst = list) != null && (a = lst.elementData) != null) {
if ((hi = fence) < 0) {
mc = lst.modCount;
hi = lst.size;
}
else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
/**
* 获取切割迭代器的元素个数
* 计算结束索引与起始索引之间的元素个数
* @return 切割迭代器的元素个数
*/
public long estimateSize() {
return (long) (getFence() - index);
}
/**
* 获取切割迭代器的特征值
* ArrayList底层实现是数组,故是有序、有实际大小、可重复、可存入null、属于非线程安全、在遍历时可添加修改替换元素
*/
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
分割迭代器可以单个(tryAdvance)或顺序(多个)遍历元素。
分割迭代器可拆分成若干个小型的分割迭代器来并行操作元素。
分割迭代器属于非线程安全。
ArrayListSpliterator属于后期绑定与快速失败的分割迭代器。
标签:现在 bool false advance 初始 inter iter ati 前言
原文地址:https://www.cnblogs.com/zlia/p/14157309.html