В чём разница терминальных операций в Java Stream API: count() и collect(Collectors.counting())?

count() и

collect(Collectors.counting())

Не дублирующий ли это функционал? Или есть какая-то разница, тогда что предпочтительнее использовать?

Я пока не нашёл ситуаций, где второй не мог бы заменить первый.


Ответы (2 шт):

Автор решения: TiBi

Вместо .collect(Collectors.counting()) лучше использовать .count(), т.к. это более читаемо и по-сути делает то же самое.

Но Collectors.counting() может пригодиться для других целей, например его можно использовать в коллекторах вроде Collectors.groupingBy, Collectors.collectingAndThen и т.д.

Пример

Есть класс продукта:

public class Product {
    private final String name;               // имя продукта
    private final String manufacturerName;   // имя производителя

    // далле конструкоры, геттеры и т.д.
    //...
}

и список продуктов:

List<Product> products = Arrays.asList(
                new Product("product1", "manufacturer1"),
                new Product("product2", "manufacturer2"),
                new Product("product3", "manufacturer1")
        );

Допустим, что нужно получить Map, в котором ключ - это имя производителя, а значение - количество произведенных продуктов. Сделать это можно с использованием Collectors.counting (будет выглядеть менее громоздко, если использовать статические импорты):

products
    .stream()
    .collect(Collectors.groupingBy(Product::getManufacturerName, Collectors.counting()))

Результат выполнения: {manufacturer1=2, manufacturer2=1}

→ Ссылка
Автор решения: Serodv

Терминальный метод count() обладает одной интересной собенностью - если в цепочке промежуточных операций не будет операций изменения количества данных источника (например filter()), то эти промежуточные операции не будут выполняться. По сути компилятор производит оптимизацию для ускорения получения результата. Например:

list.stream().map(Object::toString).peek(System.out::println).count();

ничего не выведет на консоль, в то время как collect(Collectors.counting()) обеспечит стандартное выполнение всех методов в цепочке.

→ Ссылка