Как выполнять функции 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
, который мне не хватает?
Ответы
Ответ 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
.