«1. Обзор

В этом руководстве мы рассмотрим использование метода Stream.count(). В частности, мы увидим, как мы можем комбинировать метод count() с методом filter() для подсчета совпадений с примененным предикатом.

2. Использование Stream.count()

Сам метод count() предоставляет небольшую, но очень полезную функциональность. Мы также можем превосходно комбинировать его с другими инструментами, например, с Stream.filter().

Давайте воспользуемся тем же классом Customer, который мы определили в нашем руководстве для Stream.filter():

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

Кроме того, мы также создадим ту же коллекцию клиентов:

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

Далее, Применим методы Stream к списку, чтобы отфильтровать его и определить, сколько совпадений получат наши фильтры.

2.1. Подсчет элементов

Давайте посмотрим на самое простое использование count():

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

assertThat(count).isEqualTo(4L);

Обратите внимание, что count() возвращает длинное значение.

2.2. Использование count() с filter()

Пример из предыдущего подраздела не впечатлил. К такому же результату мы могли бы прийти и с методом List.size().

Stream.count() действительно сияет, когда мы комбинируем его с другими методами Stream — чаще всего с filter():

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

assertThat(countBigCustomers).isEqualTo(2L);

В этом примере мы применили фильтр к списку клиентов, и мы также получили количество клиентов, которые выполняют условие. В данном случае у нас есть два клиента с более чем 100 баллами.

Конечно, может случиться так, что ни один элемент не соответствует нашему фильтру:

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

assertThat(count).isEqualTo(0L);

2.3. Использование count() с расширенными фильтрами

В нашем руководстве по filter() мы видели несколько более сложных вариантов использования этого метода. Конечно, мы все равно можем подсчитать результат таких операций filter().

Мы можем фильтровать коллекции по нескольким критериям:

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

assertThat(count).isEqualTo(1L);

Здесь мы отфильтровали и подсчитали количество клиентов, чьи имена начинаются с «Чарльз» и которые набрали более 10 баллов.

Мы также можем выделить критерии в отдельный метод и использовать ссылку на метод:

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

assertThat(count).isEqualTo(2L);

3. Заключение

В этой статье мы рассмотрели несколько примеров использования метода count() в сочетании с метод filter() для обработки потоков. Для дальнейшего использования count() ознакомьтесь с другими методами, которые возвращают Stream, например, показанными в нашем руководстве по объединению потоков с помощью concat().

Как всегда, полный код доступен на GitHub.