这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战
1. 一次性
// 创建有限元素的流
Stream<Integer> finiteStream = Stream.of(1, 2, 3);
// 第一次消费流
finiteStream.forEach(System.out::println);
// 第二次消费, 抛异常 IllegalStateException: stream has already been operated upon or closed
finiteStream.forEach(System.out::println);
2. 链式定义
Stream.of(1, 2, 3, 4, 5, 6, 7, 8)
.filter(x -> x % 2 == 0)
.forEach(System.out::println);
/* 输出:
2
4
6
8
*/
3. 延迟执行
- terminal operation:最终操作,如 .collect、.iterator、.spliterator、.forEach 方法。
- intermediate operation:中间操作,如 .filter、.map、.onClose 方法。会返回一条新的 Stream,延迟执行。
(1)创建无限递增整数的流
Stream<Integer> infiniteStream = Stream.iterate(0, x -> {
System.out.println("init: " + (x + 1));
return x + 1;
});
// 实际上仅当调用到其中的元素,流才会被初始化
infiniteStream.limit(4).forEach(System.out::println);
/* 输出:
0
init: 1
1
init: 2
2
init: 3
3
*/
(2)创建无限生成随机数的流
Random random = new Random(System.currentTimeMillis());
Stream<Integer> randomStream = Stream.generate(random::nextInt);
randomStream.limit(3).forEach(System.out::println);
4. 可并发
// .parallel() 使用 fork-join 框架
// 可以自行设置并发线程数, 默认使用 CPU 核心数作为
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4");
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).parallel().filter(x -> x % 2 == 0).map(x -> x << 1).forEach(System.out::println);
// 最终乱序输出
5. 聚合分组
主要结合 .collect(...) 方法,实现数据分组、聚合计算。
(1)简单求和
System.out.println(Stream.of(1, 2, 3, 4).reduce(0, (oldOne, newOne) -> oldOne + newOne, Integer::sum));
/* 输出:
10
*/
(2)汇聚合并成 List
List<Integer> intList = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).collect(Collectors.toList());
(3)分组合并成 List
Map<Integer, List<Integer>> intGroupMap = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
.collect(Collectors.groupingBy(x -> x % 4));
intGroupMap.entrySet().forEach(System.out::println);
/* 输出:
0=[4, 8, 12, 16]
1=[1, 5, 9, 13]
2=[2, 6, 10, 14]
3=[3, 7, 11, 15]
*/
(4)分组求和
Map<Integer, Integer> intSumMap = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
.collect(Collectors.toMap(x -> x % 4, a -> a, Integer::sum));
intSumMap.entrySet().forEach(System.out::println);
/* 输出:
0=40
1=28
2=32
3=36
*/
6. 顺序
(1)并发乱序
Stream.of(3,1,2).parallel().forEach(System.out::println);
/* 输出: 随机顺序,略 */
(1)并发顺序
Stream.of(3,1,2).parallel().forEachOrdered(System.out::println);
/* 输出:
3
1
2
*/