Konwersja Iterable do Stream przy użyciu Java 8 JDK
Mam interfejs, który zwraca java.lang.Iterable<T>
.
Chciałbym manipulować tym wynikiem za pomocą Java 8 Stream API.
Iterable nie może jednak "streamować".
Jakiś pomysł, jak użyć Iterable jako strumienia bez konwersji go do listy?
9 answers
Jest o wiele lepsza odpowiedź niż użycie spliteratorUnknownSize
bezpośrednio, co jest zarówno łatwiejsze, jak i daje lepszy wynik. Iterable
ma metodę spliterator()
, więc powinieneś jej użyć, aby uzyskać swój spliterator. W najgorszym przypadku jest to ten sam kod (Domyślna implementacja używa spliteratorUnknownSize
), ale w bardziej powszechnym przypadku, gdy twoja Iterable
jest już kolekcją, otrzymasz lepszy spliterator, a tym samym lepszą wydajność strumienia (może nawet dobrą równoległość). Jest też mniej kodu:
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
As you can zobacz, uzyskanie strumienia z Iterable
(patrz również to pytanie ) nie jest zbyt bolesne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 16:23:26
Jeśli możesz używać biblioteki Guava, od wersji 21, możesz użyć
Streams.stream(iterable)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 09:11:18
Możesz łatwo utworzyć Stream
z Iterable
lub Iterator
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-08 13:53:59
Chciałbym zasugerować Użycie biblioteki JOOL , która ukrywa magię spliteratora za wywołaniem Seq.seq(iterable)
, a także zapewnia całą masę dodatkowych przydatnych funkcjonalności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-11 19:39:27
Tak jak inna odpowiedź wspomniana Guava ma wsparcie dla tego za pomocą:
Streams.stream(iterable);
Chcę podkreślić, że implementacja robi coś nieco innego niż inne sugerowane odpowiedzi. Jeśli {[2] } jest typu Collection
, rzucają go.
public static <T> Stream<T> stream(Iterable<T> iterable) {
return (iterable instanceof Collection)
? ((Collection<T>) iterable).stream()
: StreamSupport.stream(iterable.spliterator(), false);
}
public static <T> Stream<T> stream(Iterator<T> iterator) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, 0),
false
);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-03 12:09:53
I ' ve created this class:
public class Streams {
/**
* Converts Iterable to stream
*/
public static <T> Stream<T> streamOf(final Iterable<T> iterable) {
return toStream(iterable, false);
}
/**
* Converts Iterable to parallel stream
*/
public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
return toStream(iterable, true);
}
private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
return StreamSupport.stream(iterable.spliterator(), isParallel);
}
}
Myślę, że jest doskonale czytelny, ponieważ nie musisz myśleć o spliteratorach i booleanach (isParallel).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-21 10:31:49
Bardzo prostym obejściem tego problemu jest utworzenie Streamable<T>
interfejsu rozszerzającego Iterable<T>
, który zawiera metodę default <T> stream()
.
interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
Teraz każdy z twoich Iterable<T>
s może być trywialnie streamowalny tylko przez zadeklarowanie ich implements Streamable<T>
zamiast Iterable<T>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-09 10:27:45
Jeśli zdarzy ci się użyć Vavr (wcześniej znanego jako Javaslang), może to być tak proste, jak:
Iterable i = //...
Stream.ofAll(i);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 17:30:53
Inny sposób, aby to zrobić, z Java 8 i bez zewnętrznych bibliotek:
Stream.concat(collectionA.stream(), collectionB.stream())
.collect(Collectors.toList())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-10 10:44:40