Подтвердить что ты не робот

Группировка потока Java8 без его сбора

Есть ли способ в Java 8 сгруппировать элементы в java.util.stream.Stream без их сбора? Я хочу, чтобы результат снова был Stream. Поскольку мне приходится работать с большим количеством данных или даже бесконечными потоками, я не могу сначала собрать данные и снова передать результат.

Все элементы, которые необходимо сгруппировать, являются последовательными в первом потоке. Поэтому мне нравится поддерживать ленивый поток.

4b9b3361

Ответ 1

Нет никакого способа сделать это, используя стандартный Stream API. В общем, вы не можете сделать это, так как всегда возможно, что в будущем будет отображаться новый элемент, который принадлежит к любой из уже созданных групп, поэтому вы не можете передать свою группу в анализ вниз, пока не обработаете все входные данные.

Однако, если вы заранее знаете, что элементы, которые должны быть сгруппированы, всегда смежны во входном потоке, вы можете решить свою проблему, используя сторонние библиотеки, улучшающие Stream API. Одна из таких библиотек - StreamEx, которая свободна и написана мной. Он содержит ряд операторов "частичной редукции", которые сворачивают соседние элементы в отдельные на основе некоторого предиката. Обычно вы должны указать BiPredicate, который проверяет два соседних элемента и возвращает true, если они должны быть сгруппированы вместе. Ниже перечислены некоторые операции частичного восстановления:

  • collapse(BiPredicate): замените каждую группу на первый элемент группы. Например, collapse(Objects::equals) полезен для удаления соседних дубликатов из потока.
  • groupRuns(BiPredicate): замените каждую группу на список элементов группы (поэтому StreamEx<T> преобразуется в StreamEx<List<T>>). Например, stringStream.groupRuns((a, b) -> a.charAt(0) == b.charAt(0)) создаст поток списков строк, в котором каждый список содержит смежные строки, начинающиеся с той же буквы.

Другие операции частичного сокращения включают intervalMap, runLengths() и т.д.

Все операции частичного сокращения являются ленивыми, параллельными и эффективными.

Обратите внимание, что вы можете легко построить объект StreamEx из обычного потока Java 8, используя StreamEx.of(stream). Также есть методы для его создания из массива, Collection, Reader и т.д. Класс StreamEx реализует интерфейс Stream и 100% совместим со стандартным Stream API.