目录
数据流
数据流是一系列数据,允许以顺序或并行方式将一系列操作(通常用lambda表达式来表示)应用于其中,以过滤、转换、分类、减少或构建新的数据结构。
这些数据流是基于Stream接口以及java.util.stream包中包含的一些相关的类和接口的。另外你可以从实现Collection接口的每个数据结构上创建一个Stream接口,这些数据来自File、Directory、Array和其他源。
Java还提供了不同的机制,通过它们为自己的源创建流,其中最重要的如下:
- Supplier接口:该接口定义get()方法。当Stream需要处理另一个对象时,它将由Stream调用。可以使用Stream类的generate静态方法,并利用Supplier接口来创建Stream。
- Stream.Builder接口:该接口提供了向Stream中添加元素的accept()和add()元素,以及build方法,该方法返回使用之前元素创建的Stream接口。
- Spliterator接口:该接口定义了遍历和拆分源元素的必要方法。可以使用StreamSupport类的stream()方法生成Stream接口来处理Spliterator的元素。(本文主要讲该方法)
一、主程序
package xyz.jangle.thread.test.n8_xii.stream;
import java.util.stream.StreamSupport;
/**
* 8.12、实现自己的流生成器
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年10月12日 下午6:46:22
*
*/
public class M {
public static void main(String[] args) {
Item[][] items;
items = new Item[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
var it = items[i][j] = new Item();
it.setRow(i);
it.setColumn(j);
it.setName("Item " + i + " " + j);
}
}
var mySpliterator = new MySpliterator(items, 0, items.length);
// 重要 1、先执行trySplit方法来分割数据源(parallel参数为true, 若为false则直接执行2)
// 2、调用forEachRemaining方法来处理
// 3、(forEachRemaining委托tryAdvance方法执行)
StreamSupport.stream(mySpliterator, true)
.forEach(item -> System.out.println(Thread.currentThread().getName() + ":" + item.getName()));
}
}
二、元素类
package xyz.jangle.thread.test.n8_xii.stream;
/**
* 元素类
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年10月13日 下午4:48:12
*
*/
public class Item {
private String name;
private int row, column;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
}
三、自定义分离器
package xyz.jangle.thread.test.n8_xii.stream;
import java.util.Spliterator;
import java.util.function.Consumer;
/**
* 自定义分离器
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年10月13日 下午4:50:12
*
*/
public class MySpliterator implements Spliterator<Item> {
private Item[][] items;
private int start, end, current;
public MySpliterator(Item[][] items, int start, int end) {
super();
this.items = items;
this.start = start;
this.end = end;
this.current = start;
}
@Override
public boolean tryAdvance(Consumer<? super Item> action) {
System.out.println("tryAdvance: start :" + start + "," + end + "," + current);
if (current < end) {
for (int i = 0; i < items[current].length; i++) {
action.accept(items[current][i]);
}
current++;
System.out.println("tryAdvance: end:true");
return true;
}
System.out.println("tryAdvance: end:false");
return false;
}
@Override
public void forEachRemaining(Consumer<? super Item> action) {
System.out.println("forEachRemaining:start");
Spliterator.super.forEachRemaining(action);
System.out.println("forEachRemaining:end");
}
@Override
public Spliterator<Item> trySplit() {
System.out.println("trySplit:start");
if (end - start <= 2) {
System.out.println("trySplit:end");
return null;
}
int mid = start + ((end - start) / 2);
int newStart = mid;
int newEnd = end;
end = mid;
System.out.println("trySplit:end : start=" + start + ",mid=" + mid + ",end=" + end + ",newStart=" + newStart
+ ",newEnd=" + newEnd + ",current=" + current);
return new MySpliterator(items, newStart, newEnd);
}
@Override
public long estimateSize() {
return end - current;
}
@Override
public int characteristics() {
return ORDERED | SIZED | SUBSIZED;
}
}
四、执行结果
trySplit:start
trySplit:end : start=0,mid=5,end=5,newStart=5,newEnd=10,current=0
trySplit:start
trySplit:end : start=0,mid=2,end=2,newStart=2,newEnd=5,current=0
trySplit:start
trySplit:end : start=2,mid=3,end=3,newStart=3,newEnd=5,current=2
forEachRemaining:start
tryAdvance: start :2,3,2
main:Item 2 0
main:Item 2 1
main:Item 2 2
main:Item 2 3
trySplit:start
trySplit:start
main:Item 2 4
main:Item 2 5
trySplit:start
trySplit:end
forEachRemaining:start
tryAdvance: start :0,2,0
main:Item 2 6
main:Item 2 7
trySplit:end
forEachRemaining:start
tryAdvance: start :3,5,3
ForkJoinPool.commonPool-worker-7:Item 3 0
ForkJoinPool.commonPool-worker-7:Item 3 1
ForkJoinPool.commonPool-worker-7:Item 3 2
trySplit:end : start=5,mid=7,end=7,newStart=7,newEnd=10,current=5
ForkJoinPool.commonPool-worker-7:Item 3 3
ForkJoinPool.commonPool-worker-7:Item 3 4
ForkJoinPool.commonPool-worker-7:Item 3 5
main:Item 2 8
main:Item 2 9
ForkJoinPool.commonPool-worker-5:Item 0 0
ForkJoinPool.commonPool-worker-5:Item 0 1
ForkJoinPool.commonPool-worker-5:Item 0 2
ForkJoinPool.commonPool-worker-5:Item 0 3
tryAdvance: end:true
tryAdvance: start :2,3,3
tryAdvance: end:false
forEachRemaining:end
trySplit:start
trySplit:start
trySplit:end
forEachRemaining:start
ForkJoinPool.commonPool-worker-7:Item 3 6
ForkJoinPool.commonPool-worker-7:Item 3 7
ForkJoinPool.commonPool-worker-7:Item 3 8
ForkJoinPool.commonPool-worker-7:Item 3 9
tryAdvance: end:true
tryAdvance: start :3,5,4
ForkJoinPool.commonPool-worker-7:Item 4 0
ForkJoinPool.commonPool-worker-7:Item 4 1
ForkJoinPool.commonPool-worker-7:Item 4 2
ForkJoinPool.commonPool-worker-7:Item 4 3
ForkJoinPool.commonPool-worker-7:Item 4 4
ForkJoinPool.commonPool-worker-7:Item 4 5
ForkJoinPool.commonPool-worker-7:Item 4 6
tryAdvance: start :5,7,5
ForkJoinPool.commonPool-worker-3:Item 5 0
ForkJoinPool.commonPool-worker-3:Item 5 1
ForkJoinPool.commonPool-worker-3:Item 5 2
ForkJoinPool.commonPool-worker-3:Item 5 3
ForkJoinPool.commonPool-worker-3:Item 5 4
ForkJoinPool.commonPool-worker-3:Item 5 5
ForkJoinPool.commonPool-worker-3:Item 5 6
ForkJoinPool.commonPool-worker-3:Item 5 7
trySplit:end : start=7,mid=8,end=8,newStart=8,newEnd=10,current=7
ForkJoinPool.commonPool-worker-5:Item 0 4
ForkJoinPool.commonPool-worker-5:Item 0 5
ForkJoinPool.commonPool-worker-5:Item 0 6
ForkJoinPool.commonPool-worker-5:Item 0 7
ForkJoinPool.commonPool-worker-5:Item 0 8
ForkJoinPool.commonPool-worker-5:Item 0 9
tryAdvance: end:true
tryAdvance: start :0,2,1
trySplit:start
trySplit:end
forEachRemaining:start
tryAdvance: start :8,10,8
ForkJoinPool.commonPool-worker-11:Item 8 0
ForkJoinPool.commonPool-worker-11:Item 8 1
ForkJoinPool.commonPool-worker-11:Item 8 2
ForkJoinPool.commonPool-worker-11:Item 8 3
ForkJoinPool.commonPool-worker-11:Item 8 4
ForkJoinPool.commonPool-worker-3:Item 5 8
ForkJoinPool.commonPool-worker-3:Item 5 9
tryAdvance: end:true
ForkJoinPool.commonPool-worker-7:Item 4 7
ForkJoinPool.commonPool-worker-7:Item 4 8
ForkJoinPool.commonPool-worker-7:Item 4 9
tryAdvance: end:true
tryAdvance: start :5,7,6
ForkJoinPool.commonPool-worker-3:Item 6 0
ForkJoinPool.commonPool-worker-3:Item 6 1
ForkJoinPool.commonPool-worker-3:Item 6 2
ForkJoinPool.commonPool-worker-3:Item 6 3
ForkJoinPool.commonPool-worker-3:Item 6 4
ForkJoinPool.commonPool-worker-11:Item 8 5
ForkJoinPool.commonPool-worker-5:Item 1 0
forEachRemaining:start
ForkJoinPool.commonPool-worker-5:Item 1 1
ForkJoinPool.commonPool-worker-11:Item 8 6
ForkJoinPool.commonPool-worker-3:Item 6 5
tryAdvance: start :3,5,5
tryAdvance: end:false
forEachRemaining:end
ForkJoinPool.commonPool-worker-3:Item 6 6
ForkJoinPool.commonPool-worker-11:Item 8 7
ForkJoinPool.commonPool-worker-5:Item 1 2
tryAdvance: start :7,8,7
ForkJoinPool.commonPool-worker-5:Item 1 3
ForkJoinPool.commonPool-worker-11:Item 8 8
ForkJoinPool.commonPool-worker-3:Item 6 7
ForkJoinPool.commonPool-worker-3:Item 6 8
ForkJoinPool.commonPool-worker-3:Item 6 9
tryAdvance: end:true
ForkJoinPool.commonPool-worker-11:Item 8 9
tryAdvance: end:true
ForkJoinPool.commonPool-worker-5:Item 1 4
ForkJoinPool.commonPool-worker-9:Item 7 0
ForkJoinPool.commonPool-worker-9:Item 7 1
ForkJoinPool.commonPool-worker-5:Item 1 5
tryAdvance: start :8,10,9
tryAdvance: start :5,7,7
tryAdvance: end:false
forEachRemaining:end
ForkJoinPool.commonPool-worker-11:Item 9 0
ForkJoinPool.commonPool-worker-5:Item 1 6
ForkJoinPool.commonPool-worker-9:Item 7 2
ForkJoinPool.commonPool-worker-5:Item 1 7
ForkJoinPool.commonPool-worker-11:Item 9 1
ForkJoinPool.commonPool-worker-5:Item 1 8
ForkJoinPool.commonPool-worker-9:Item 7 3
ForkJoinPool.commonPool-worker-5:Item 1 9
tryAdvance: end:true
ForkJoinPool.commonPool-worker-11:Item 9 2
tryAdvance: start :0,2,2
tryAdvance: end:false
forEachRemaining:end
ForkJoinPool.commonPool-worker-9:Item 7 4
ForkJoinPool.commonPool-worker-11:Item 9 3
ForkJoinPool.commonPool-worker-9:Item 7 5
ForkJoinPool.commonPool-worker-9:Item 7 6
ForkJoinPool.commonPool-worker-11:Item 9 4
ForkJoinPool.commonPool-worker-9:Item 7 7
ForkJoinPool.commonPool-worker-11:Item 9 5
ForkJoinPool.commonPool-worker-9:Item 7 8
ForkJoinPool.commonPool-worker-11:Item 9 6
ForkJoinPool.commonPool-worker-9:Item 7 9
tryAdvance: end:true
ForkJoinPool.commonPool-worker-11:Item 9 7
tryAdvance: start :7,8,8
tryAdvance: end:false
forEachRemaining:end
ForkJoinPool.commonPool-worker-11:Item 9 8
ForkJoinPool.commonPool-worker-11:Item 9 9
tryAdvance: end:true
tryAdvance: start :8,10,10
tryAdvance: end:false
forEachRemaining:end