ArrayList源码分析(下)——从ArrayList中分析Java8新增的方法
从集合的最基本的接口Collection中可以看出Java8中新增了下面几点内容:
1. spliterator
2. stream
3. parallelStream
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
1. spliterator
从源码中可以看出spiterator返回一个Spliterator对象。
Spliterator用于遍历和分隔一个对象中的元素,这个对象必须实现Spliterator接口,实现这个接口类有Collection,数组等。
Spliterator可以逐个的遍历元素,或者批量的遍历。
Spliterator是一个可以分割的迭代器,可以将Spilterator实例分割成多个小的Spilterator实例。
下面的是Spliterator中的一些特征值:
// 表示迭代器需要按照原始的顺序迭代器中的元素
public static final int ORDERED = 0x00000010;
// 迭代器中的元素是没音重复的
public static final int DISTINCT = 0x00000001;
// 按照某种排序方式的顺序迭代其中的元素
public static final int SORTED = 0x00000004;
// 表示迭代器中的元素的个数是可计数的,有界的
public static final int SIZED = 0x00000040;
// 迭代器中的元素是非空的
public static final int NONNULL = 0x00000100;
// 迭代器中的元素是不可以改变的,不能增加也不能替换和删除。
public static final int IMMUTABLE = 0x00000400;
// 表示迭代器的数据源是线程安全的`
public static final int CONCURRENT = 0x00001000;
// 表示当前的迭代器的所有的子迭代器(直接的或者间接的),都是'SIZED'和SUBSIZED的
public static final int SUBSIZED = 0x00004000;
}
下面的是Spliterator中的一些方法:
public interface Spliterator<T> {
// 如果有元素剩余,那么执行action,并返回true,如果没有元素剩余,返回false
boolean tryAdvance(Consumer<? super T> action);
// 对当前的线程中的元素执行给定的操作,直到所有的元素被处理或者抛出异常
default void forEachRemaining(Consumer<? super T> action) {
// 从这里也可以看出tryAdvance的用法
do { } while (tryAdvance(action));
}
// 将一个Spliterator。分割的Spliterator可以被用于每个子线程进行处理,从而达到并发的效果
Spliterator<T> trySplit();
// 返回forEachRemain()需要遍历元素总数的估计值,如果这个结果是无穷大,未计数的,那么返回
long estimateSize();
// 如果当前线程是可以计算剩余元素的总数,那么返回剩余元素的总数,否则返回-1
default long getExactSizeIfKnown() {
// 这里利用了与、或运算,可以先看下面的
return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
}
// 返回此Spliterator及其元素的一组特征值,这些结果表示为(ORDERED , DISTINCT , SORTED , SIZED , NONNULL , IMMUTABLE , CONCURRENT , SUBSIZED )的或运算
// 如果符合该Spliterator有什么特性,那么代表那个属性的那一位就是1,否则就是0
int characteristics();
// Spliterator是否有执行的特性,
// 这里同样使用了位运算的特性
default boolean hasCharacteristics(int characteristics) {
return (characteristics() & characteristics) == characteristics;
}
// 如果这个Spilterator的数据源是可排序的,如果数据源是自然排序,返回null。 如果数据源不是SORTED,则抛出IllegalStateException
default Comparator<? super T> getComparator() {
throw new IllegalStateException();
}
下面的这个是Spliterator的一个内部接口,这个接口继承了Spliterator这个接口。
/**
* @param <T> 此Spliterator的返回类型,该类型必须是原始类型的包装类型,如Integer的原始类型int类型
* @param <T_CONS> 原始消费者类型Consumer,必须和T对应,例如Integer对应IntConsumer
* @param <T_SPLITR> 原始的Spilterator。该类型和上面的一样,必须和T对应
* 这么说可能还是不好理解,可以看下面的一个实现
*/
public interface OfPrimitive<T, T_CONS, T_SPLITR extends java.util.Spliterator.OfPrimit
extends java.util.Spliterator<T> {
@Override
T_SPLITR trySplit();
@SuppressWarnings("overloads")
boolean tryAdvance(T_CONS action);
@SuppressWarnings("overloads")
default void forEachRemaining(T_CONS action) {
do { } while (tryAdvance(action));
}
}
public interface OfInt extends java.util.Spliterator.OfPrimitive<Integer, IntConsumer, java.util.Spliterato
@Override
OfInt trySplit();
@Override
boolean tryAdvance(IntConsumer action);
@Override
default void forEachRemaining(IntConsumer action) {
do { } while (tryAdvance(action));
}
@Override
default boolean tryAdvance(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
return tryAdvance((IntConsumer) action);
}
else {
if (Tripwire.ENABLED) // 如果Boolea系统的属性org.openjdk.java.util.stream.tripwire设置为true
Tripwire.trip(getClass(), // 那么这里会出现警告
"{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
return tryAdvance((IntConsumer) action::accept);
}
}
@Override
default void forEachRemaining(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
forEachRemaining((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
forEachRemaining((IntConsumer) action::accept);
}
}
}
下面的这个是ArrayList中获取分割器的一个实现:
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
下面的就是ArrayList中的ArrayListSpliterator的实现:
/**
* 基于索引的、二分的、懒加载器
* Index-based split-by-two, lazily initialized Spliterator
*/
static final class ArrayListSpliterator<E> implements Spliterator<E> {
// 用于存放ArrayList对象
private final ArrayList<E> list;
// 当前位置(包含),advance/spilt操作时会被修改
private int index; // current index, modified on advance/split
// 结束位置(不包含),-1表示到最后一个元素
private int fence; // -1 until used; then one past last index
// 用于存放list的modCount
private 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 traversed
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
// 第一次使用时实例化结束位置
private int getFence() { // initialize fence to size on first use
int hi; // (a specialized variant appears in method forEach)
ArrayList<E> lst;
// 第一次初始化时,fence才会小于0
if ((hi = fence) < 0) {
// 如果集合中没有元素
if ((lst = list) == null)
hi = fence = 0;
else {
expectedModCount = lst.modCount;
hi = fence = lst.size;
}
}
return hi;
}
// 分割list,返回一个返回一个新分割出的spilterator实例
// 相当于二分法,这个方法会递归
// 1. ArrayListSpilterator本质还是对原list进行操作,只是通过index和fence来控制每次处理的范围
public ArrayListSpliterator<E> trySplit() {
// hi结束位置(不包括) lo:开始位置 mid中间位置
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
// 当lo >= mid, 表示不能再分割
// 当lo < mid时,表示可以分割,切割(lo, mid)出去,同时更新index = mid
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<E>(list, lo, index = mid,
expectedModCount);
}
/**
* 返回true时,表示可能还有元素未处理
* 返回falsa时,没有剩余元素处理了
*
* @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();
// 如果list不为空,且list中的元素不为空
if ((lst = list) != null && (a = lst.elementData) != null) {
// 当fence < 0 时,表示fence和exceptModCount未初始化
if ((hi = fence) < 0) {
mc = lst.modCount;
hi = lst.size;
} else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
// 估算大小
public long estimateSize() {
return (long) (getFence() - index);
}
// 返回特征值
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}