Spliterator是Java 8中加入的另一个新接口;这个名字代表“可分迭代器”(splitableiterator)。和Iterator一样,Spliterator也用于遍历数据源中的元素,但它是为了并行执行而设计的。
自定义Spliterator需要实现Spliterator接口。
public interface Spliterator<T> {
boolean tryAdvance(Consumer<? super T> action);
Spliterator<T> trySplit();
long estimateSize();
int characteristics();
}
T:Spliterator遍历的元素的类型
tryAdvance:类似于普通的Iterator,因为它会按顺序一个一个使用Spliterator中的元素,并且如果还有其他元素要遍历就返回true。
trySplit:把一些元素划出去分给第二个Spliterator(由该方法返回),让它们两个并行处理。
estimateSize:估计还剩下多少元素要遍历,让拆分均匀一点。
characteristics
特 性 | 含 义 |
---|---|
ORDERED | 元素有既定的顺序(例如List),因此Spliterator在遍历和划分时也会遵循这一顺序 |
DISTINCT | 对于任意一对遍历过的元素x和y,x.equals(y)返回false |
SORTED | 遍历的元素按照一个预定义的顺序排序 |
SIZED | 该Spliterator由一个已知大小的源建立(例如Set),因此estimatedSize()返回的是准确值 |
NONNULL | 保证遍历的元素不会为null |
IMMUTABLE | Spliterator的数据源不能修改。这意味着在遍历时不能添加、删除或修改任何元素 |
CONCURRENT | 该Spliterator的数据源可以被其他线程同时修改而无需同步 |
SUBSIZED | 该Spliterator和所有从它拆分出来的Spliterator都是SIZED |
package com.morris.java8.parallel;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class IntSpliterator implements Spliterator<Integer> {
private int start;
private int end;
private int current;
private int[] data;
public Stream<Integer> stream() {
return StreamSupport.stream(this, false);
}
public Stream<Integer> parallelStream() {
return StreamSupport.stream(this, true);
}
public IntSpliterator(int[] data) {
this(0, data.length, data);
}
public IntSpliterator(int start, int end, int[] data) {
this.start = start;
this.end = end;
this.current = start;
this.data = data;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
if(current < end) {
action.accept(data[current++]);
return true;
}
return false;
}
@Override
public Spliterator<Integer> trySplit() {
if(start - end <= 2) {
return null;
}
int mid=start+((end-start)/2);
int newStart=mid;
int newEnd=end;
end=mid;
return new IntSpliterator(newStart, newEnd, data);
}
@Override
public long estimateSize() {
return data.length - end;
}
@Override
public int characteristics() {
return Spliterator.ORDERED|Spliterator.SUBSIZED|Spliterator.SIZED;
}
public static void main(String[] args) {
int[] ints = IntStream.rangeClosed(1, 10).toArray();
IntSpliterator intSpliterator = new IntSpliterator(ints);
intSpliterator.stream().forEach(System.out::println);
//intSpliterator.parallelStream().forEach(System.out::print);
}
}