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

Как выполнять функции Stream на Iterable?

В Java 8 класс Stream не имеет способа обернуть a Iterable.

Вместо этого я получаю Spliterator из Iterable, а затем получаю a Stream из StreamSupport следующим образом:

boolean parallel = true;

StreamSupport.stream(spliterator(), parallel)
                .filter(Row::isEmpty)
                .collect(Collectors.toList())
                .forEach(this::deleteRow);

Есть ли другой способ генерации операций Stream на Iterable, который мне не хватает?

4b9b3361

Ответ 1

Мой подобный вопрос получил обозначение как дубликат, но вот вспомогательные методы, которые я использовал, чтобы избежать некоторых шаблонов:

public static <T> Stream<T> stream(Iterable<T> in) {
    return StreamSupport.stream(in.spliterator(), false);
}

public static <T> Stream<T> parallelStream(Iterable<T> in) {
    return StreamSupport.stream(in.spliterator(), true);
}

Ответ 2

То, что вы описываете, это способ получить поток из Iterable. Поэтому они добавили метод spliterator() в Iterable. Я сделал то же самое преобразование и не видел другого пути.

[UPDATE] Возможно, этот другой ответ прояснит некоторые причины "почему".

Ответ 3

Я знаю, что это прямо не отвечает на ваш вопрос, но у приличного количества Iterable-источников, таких как коллекции, теперь есть метод для получения объекта как потока.

Я думаю, что трение, которое вы столкнетесь с этим вопросом, заключается в том, что Iterable является семантически последовательным, тогда как Spliterators предназначены для параллельной обработки. Вероятно, лучше реализовать Spliterator для базового источника данных, который вас интересует, если он еще не предоставлен в JDK, потому что просто использование обертки вокруг Iterable не позволит вам получить преимущества, предоставляемые Stream API (например, параллельная обработка).

Ответ 4

Вот как я добавил функциональность потока в Iterable<T>.

public interface StreamableIterable<T> extends Iterable<T> {

   public default Stream<T> stream() {
      final Stream.Builder<T> streamBuilder = Stream.builder();
      forEach(t -> streamBuilder.add(t));
      return streamBuilder.build();
   }
}

Не уверен, что это правильный путь, но он довольно просто создает поток из Iterable.