1. Overview

In this tutorial, we’ll explore the use of the Stream.count() method. Specifically, we’ll see how we can combine the count() method with the filter() method to count the matches of a Predicate we’ve applied.

2. Using Stream.count()

The count() method itself provides a small but very useful functionality. We can also combine it excellently with other tools, for example with Stream.filter().

Let’s use the same Customer class that we defined in our tutorial for Stream.filter():

public class Customer {
    private String name;
    private int points;
    //Constructor and standard getters
}

In addition, we also create the same collection of customers:

Customer john = new Customer("John P.", 15);
Customer sarah = new Customer("Sarah M.", 200);
Customer charles = new Customer("Charles B.", 150);
Customer mary = new Customer("Mary T.", 1);

List<Customer> customers = Arrays.asList(john, sarah, charles, mary);

Next, we’ll apply Stream methods on the list to filter it and determine how many matches our filters get.

2.1. Counting Elements

Let’s see the very basic usage of count():

long count = customers.stream().count();

assertThat(count).isEqualTo(4L);

Note that count() returns a long value.

2.2. Using count() With filter()

The example in the previous subsection wasn’t really impressive. We could have come to the same result with the List.size() method.

Stream.count() really shines when we combine it with other Stream methods – most often with filter():

long countBigCustomers = customers
  .stream()
  .filter(c -> c.getPoints() > 100)
  .count();

assertThat(countBigCustomers).isEqualTo(2L);

In this example, we’ve applied a filter on the list of customers, and we’ve also obtained the number of customers that fulfill the condition. In this case, we have two customers with more than 100 points.

Of course, it can also happen that no element matches our filter:

long count = customers
  .stream()
  .filter(c -> c.getPoints() > 500)
  .count();

assertThat(count).isEqualTo(0L);

2.3. Using count() With Advanced Filters

In our tutorial about filter(), we saw some more advanced use cases of the method. Of course, we can still count the result of such filter() operations.

We can filter collections with multiple criteria:

long count = customers
  .stream()
  .filter(c -> c.getPoints() > 10 && c.getName().startsWith("Charles"))
  .count();

assertThat(count).isEqualTo(1L);

Here, we filtered and counted the number of customers whose names start with “Charles” and who have more than 10 points.

We can also extract the criteria into its own method and use method reference:

long count = customers
  .stream()
  .filter(Customer::hasOverHundredPoints)
  .count();

assertThat(count).isEqualTo(2L);

3. Conclusion

In this article, we saw some examples of how to use the count() method in combination with the filter() method to process streams. For further use cases of count(), check out other methods that return a Stream, such as those shown in our tutorial about merging streams with concat().

As always, the complete code is available over on GitHub.