许多示例都使用.count()
作为.peek()
的终端操作,例如:
Java 8
List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();
System.out.println(count); // 4
输出–运行正常。
A
B
C
D
4
但是,对于Java 9及更高版本, peek()
可能不显示任何内容:
Java 9 and above
List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();
System.out.println(count); // 4
输出量
4
为什么peek()现在什么也不打印?
请参阅Java 9 .count() Java文档
An implementation may choose to not execute the stream pipeline (either sequentially or in parallel)
if it is capable of computing the count directly from the stream source.
In such cases no source elements will be traversed and no intermediate operations will be evaluated.
由于Java 9,如果JDK编译器能够直接从流中计算count
(Java 9中的优化),则它不会遍历流,因此根本不需要运行peek()
。
List<String> l = Arrays.asList("A", "B", "C", "D");
// JDK compiler know the size of the stream via the variable l
long count = l.stream().peek(System.out::println).count();
要强制peek()
运行,只需使用filter()
更改某些元素,或切换到另一个终端操作,例如collect()
filter()
List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream()
.filter(x->!x.isEmpty())
.peek(System.out::println)
.count();
System.out.println(count); // 4
输出量
A
B
C
D
4
collect()
List<String> l = Arrays.asList("A", "B", "C", "D");
List<String> result = l.stream()
.peek(System.out::println)
.collect(Collectors.toList());
System.out.println(result.size()); // 4
输出量
A
B
C
D
4
小心混合.peek()
与.count()
时, peek()
可能无法按预期方式工作在Java中9以上。
PS已通过Java 12测试
参考文献
翻译自: https://mkyong.com/java8/java-8-stream-the-peek-is-not-working-with-count/