Stream流编程

  • Stream 流
  • 迭代方式
  • 外部迭代
  • 内部迭代
  • 中间操作和终止操作
  • Stream流编程操作
  • 创建
  • 中间操作
  • 终止操作
  • 并行流
  • 使用自己的线程池
  • 收集器
  • Stream运行机制


Stream 流

高级的迭代器
流水线式处理思想

迭代方式

外部迭代

在业务体代码中进行循环迭代

内部迭代

int arr={1,2,3}
int sum;
int sum = IntStream.of(arr).sum();
System.out.println(sum); // -> 6

中间操作和终止操作

  • 中间操作就是返回stream可以继续其他中间操作或终止操作比如map
  • 终止操作,sum
  • 惰性求值:在终止没有被调用的情况下,中间操作也不会被调用
IntStream.of().map(lambda).sum()

Stream流编程操作

创建

类型

相关方法

描述

集合

Collection.stream/parallelStream

后者为并行流

数组

Arrays.stream

数字Stream

IntStream/LongStream.range/rangeClosed

数字Stream

Random.ints/longs/doubles

自己创建

Stream.generate/iterate

中间操作

一般一个参数的是无状态操作,两个参数的有状态操作

类型

相关方法

描述

无状态操作

map/mapToXxx

类型转化

无状态操作

flatMap/flatMapToXxx

获取A对象里的B属性的集合

无状态操作

filter

条件过滤

无状态操作

peek

入参是消费者,用于debug

无状态操作

unordered

有状态操作

distinct

有状态操作

sorted

有状态操作

limit/skip

用于无限流

终止操作

类型

相关方法

描述

非短路操作

forEach/forEachOrdered

无状态操作

collect/toArray

无状态操作

reduce

把流合成一个数据,返回一个Optional

无状态操作

min/mac/count

有状态操作

findFirst/findAny

无限流的终止条件

有状态操作

allMatch/anyMatch/noneMatch

并行流

在流操作中使用parallel使得当前操作变为并行,使用sequential产生串行流,但同次流操作只认最后的设置。

并行流使用的线程池是jdk自带的ForkJoinPool.commonPool,默认的线程数是当前机器的cpu个数。使用属性设置可以修改默认线程数:

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","10")
使用自己的线程池
ForkJoinPool pool = new ForkJoinPool(20);// 创建线程池
pool.submit(()->{
	IntStream.range(1,100).parallel().peek(LamdbaTest::debug).count();
});
pool.shutdown();//关闭线程池

收集器

尽量使用方法引用,能够提高效率,因为方法引用不会再生成一个lambda$0这样的函数

List<String> list = Arrays.asList("1","2","12312","123");
// 获取列表
list.stream().map(String::length).collect(Collectors.toList());
// 统计汇总信息
IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(String::length));
System.out.println(collect);

// 分块
Map<Boolean, List<String>> collect1 = list.stream().collect(Collectors.partitioningBy(s -> s.length() > 2));
System.out.println(collect1);

// 分组
Map<Integer, List<String>> collect2 = list.stream().collect(Collectors.groupingBy(String::length));
System.out.println(collect2);
// 分组再收集
Map<Integer, Long> collect3 = list.stream().collect(Collectors.groupingBy(String::length, Collectors.counting()));
System.out.println(collect3);

Stream运行机制

  • 所有操作是链式调用,一个元素只迭代一次
  • 每一个中间操作返回一个新的流,流里面有一个属性sourceStage执行同一个地方,就是Head
  • Head ->nextStage -> nextStage -> … -> null
  • 有状态操作会把无状态操作截断,单独处理
  • 并行环境下,有状态的中间操作不一定能并行操作
  • parallel/ sequetial也是中间操作(返回流),但是不创建流,只修改Head的并行标志