Stream.count() 与 Collectors.counting() 有什么区别

Hir*_*ada 4 java performance java-stream

接口中的count()方法Streamcounting()in 中的方法有什么区别Collectors吗?一般应该使用哪一种?使用其中之一是否有任何性能优势?

ern*_*t_k 11

一个区别在于实现。这记录在Stream.count()(至少在版本 9+ 上):

如果能够直接从流源计算计数,则实现可以选择不执行流管道(顺序或并行)。在这种情况下,不会遍历源元素,也不会评估中间操作......

尝试这个:

System.out.println(Stream.of(1, 2, 3, 4, 5)
        .map(i -> {
            System.out.println("processing " + i);
            return i * 2;
        }).count());

System.out.println(Stream.of(1, 2, 3, 4, 5)
        .map(i -> {
            System.out.println("processing " + i);
            return i * 2;
        }).collect(Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)

两者都会为您提供正确的计数,但第一个可能会跳过 的执行map(),因此可能不会显示println的输出。如文档所述,这是实现细节(count()如果可以在不执行管道的情况下确定元素数量,则可以跳过中间操作)


use*_*900 9

如果要计算(所有)元素,请使用count()

返回此流中元素的计数。这是归约的一个特例,相当于:

return mapToLong(e -> 1L).sum();
Run Code Online (Sandbox Code Playgroud)

当您需要对计数进行分组时使用计数(),如:

Map<String, Long> collect = 
   wordsList.stream().collect(groupingBy(Function.identity(), counting())); 
Run Code Online (Sandbox Code Playgroud)