What is the difference between Stream.count() vs Collectors.counting()

Viewed 751

Are there any differences between the count() method in the Stream interface vs counting() in Collectors? Which one should one use in general? Are there any performance benefits of using one over the other?

3 Answers

One difference is with the implementation. This is documented on Stream.count() (at least on versions 9+):

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...

Try this:

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()));

Both will give you the correct count, but the first one may skip the execution of map(), thus might not show println's output. As documented, this is implementation detail (count() may skip intermediate operations if it can determine the number of elements without executing the pipeline)

If you want to count (all) stream elements use count()

Returns the count of elements in this stream. This is a special case of a reduction and is equivalent to:

return mapToLong(e -> 1L).sum();

Use counting() when you need the count to be grouped, as:

Map<String, Long> collect = 
   wordsList.stream().collect(groupingBy(Function.identity(), counting())); 
   // creating a stream of strings
    Stream<String> s = Stream.of("1", "2", "3", "4");

    // using Collectors counting() method to
    // count the number of input elements
    long ans = s.collect(Collectors.counting());

    // displaying the required count
    System.out.println(ans);
Related