目录
2、filter / map / flatMap /peek
3、mapToObj / mapToLong / mapToDouble / asLongStream / asDoubleStream
6、distinct / sorted / limit / skip
7、sum / min / max / count / average / summaryStatistics
8、anyMatch / allMatch / noneMatch
Java8支持的流处理的元素类型只有4种,double、int,long和reference类型,可参考AbstractPipeline和BaseStream的类继承关系,如下:
AbstractPipeline有4个子类,分别表示流处理元素为double、int,long和reference类型的管道;这4个子类都是抽象类,每个子类下都有3个静态内部类的实现类,Head、StatefulOp、StatelessOp,其中Head用于创建一个全新的流,StatefulOp表示有状态的一类操作,StatelessOp表示无状态的一类操作,这里的有状态是指前面流元素的处理会直接影响后面流元素的处理,多线程并行处理下每次运行的结果都不相同。这4个AbstractPipeline子类的用法和实现是基本一致的,我们以IntStream为例来说明其方法使用与实现细节,本篇博客重点说明其用法。该类的类继承关系如下:
其中IntStream接口定义了int流支持的所有操作。
1、创建int流
创建int流都是由IntStream接口类中的静态方法完成的,具体如下:
- of / builder: 可指定int流中包含的具体单个元素
- range / rangeClosed : 将指定范围内的元素都添加到int流中,前者不包含最后一个元素,后者包含
- generate / iterate : 指定生成int流中int元素的生成函数,前者的生成函数没有入参,后者会将前一次调用结果作为下一次调用生成函数的入参
- concat :将两个int流合并成一个
各方法的使用细节可参考如下测试用例:
@Test
public void test() throws Exception {
//包含指定的元素
// IntStream intStream=IntStream.of(1);
//返回的int流中的元素是已经排序好的
IntStream intStream=IntStream.of(1,3,2,5,4,6);
print("of",intStream);
//从11到16,不包含16
intStream=IntStream.range(11,16);
//从11到16,包含16
// intStream=IntStream.rangeClosed(11,16);
print("range",intStream);
//包含指定的元素,add方法底层也是调用accept方法,然后返回this
//返回的int流中的元素顺序与添加顺序一致
intStream=IntStream.builder().add(23).add(22).add(21).build();
print("builder", intStream);
//指定一个int生成函数
//返回的int流中的元素不排序
intStream=IntStream.generate(()->{
Random random=new Random();
return random.nextInt(100);
}).limit(6);
print("generate", intStream);
//指定一个int生成函数,前一次执行函数的结果会作为下一次调用函数的入参
//第一个参数seed就是第一次调用生成函数的入参
//返回的int流中的元素不排序
intStream=IntStream.iterate(1,x->{
int a=2*x;
if(a>16){
return a-20;
}else{
return a;
}
}).limit(6);
print("iterate", intStream);
}
@Test
public void test2() throws Exception {
IntStream streamA=IntStream.range(11,15);
IntStream streamB=IntStream.range(6,10);
//将两个IntStream 合并起来
//返回的int流的元素顺序与添加的流的元素顺序一致,不排序
IntStream streamC=IntStream.concat(streamA,streamB);
print("concat", streamC);
}
private void print(String start, IntStream intStream){
System.out.println("print for->"+start);
intStream.forEach(x->{
System.out.println(x);
});
}
上述方法的底层实现最终都是调用StreamSupport.intStream(Spliterator.OfInt spliterator, boolean parallel)方法,如下图:
2、filter / map / flatMap /peek
filter方法会将filter函数返回false的元素从流中去除,只保留filter函数返回true的元素;map方法用于对流中的所有元素执行某个修改动作;peek方法通常用于打印流中的元素,peek函数无返回值;flatMap方法同map方法,区别在于flatMap函数的返回值是一个IntStream 而非int值,可以在返回的IntStream中包含多个元素,flatMap方法最终返回的IntStream是将每次调用flatMap函数返回的IntStream 合并后的结果。其测试用例如下:
@Test
public void test3() throws Exception {
IntStream intStream=IntStream.rangeClosed(1, 10);
//会保留过滤函数返回true的元素,此处是保留偶数
intStream=intStream.filter(x->{
return x%2==0;
}).peek(x->{ //peek方法指定的函数ÿ