Интересно, есть ли более хороший (или просто другой) подход, чтобы получить количество всех элементов, которые вводят операцию терминала в поток, а не следующее:
Stream<T> stream = ... // given as parameter
AtomicLong count = new AtomicLong();
stream.filter(...).map(...)
.peek(t -> count.incrementAndGet())
где count.get()
дает мне фактическое количество обработанных элементов на этом этапе.
Я намеренно пропустил операцию терминала, поскольку это может измениться между .forEach
, .reduce
или .collect
.
Я уже знаю .count
, но, похоже, он работает хорошо, только если я обмениваю .forEach
на .map
и использую .count
как терминальная операция. Но мне кажется, что .map
используется неправильно.
Что мне не очень нравится в вышеупомянутом решении: если после него добавляется фильтр, он просто подсчитывает элементы на этом конкретном этапе, но не те, которые входят в операцию терминала.
Другой подход, который приходит мне на ум, - это collect
отфильтрованные и отображенные значения в список, и работать с ним и просто вызвать list.size()
, чтобы получить счет. Однако это не сработает, если сбор потока приведет к ошибке, тогда как с вышеупомянутым решением я мог бы иметь счет для всех обработанных элементов до сих пор, если соответствующий try/catch
находится на месте. Это, однако, не является жестким требованием.