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的并行标志