使用 Java 8 JDK 将 Iterable 转换为 Stream
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23932061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert Iterable to Stream using Java 8 JDK
提问by rayman
I have an interface which returns java.lang.Iterable<T>
.
我有一个返回java.lang.Iterable<T>
.
I would like to manipulate that result using the Java 8 Stream API.
我想使用 Java 8 Stream API 操作该结果。
However Iterable can't "stream".
但是 Iterable 不能“流”。
Any idea how to use the Iterable as a Stream without converting it to List?
知道如何将 Iterable 用作流而不将其转换为 List 吗?
采纳答案by Brian Goetz
There's a much better answer than using spliteratorUnknownSize
directly, which is both easier and gets a better result. Iterable
has a spliterator()
method, so you should just use that to get your spliterator. In the worst case, it's the same code (the default implementation uses spliteratorUnknownSize
), but in the more common case, where your Iterable
is already a collection, you'll get a better spliterator, and therefore better stream performance (maybe even good parallelism). It's also less code:
有一个比spliteratorUnknownSize
直接使用更好的答案,它既容易又得到更好的结果。 Iterable
有一个spliterator()
方法,所以你应该用它来获取你的拆分器。在最坏的情况下,它是相同的代码(默认实现使用spliteratorUnknownSize
),但在更常见的情况下,您Iterable
已经是一个集合,您将获得更好的拆分器,从而获得更好的流性能(甚至可能是良好的并行性)。它的代码也更少:
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
As you can see, getting a stream from an Iterable
(see also this question) is not very painful.
如您所见,从Iterable
(另请参阅此问题)获取流并不是很痛苦。
回答by nosid
You can easily create a Stream
out of an Iterable
or Iterator
:
您可以轻松地创建Stream
出一个Iterable
或Iterator
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
回答by Shaggie
回答by g-t
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);
}
}
I think it's perfectly readable because you don't have to think about spliterators and booleans (isParallel).
我认为它完全可读,因为您不必考虑拆分器和布尔值 (isParallel)。
回答by numéro6
If you can use Guava library, since version 21, you can use
如果你可以使用 Guava 库,从 21 版开始,你可以使用
Streams.stream(iterable)
回答by OldCurmudgeon
A very simple work-around for this issue is to create a Streamable<T>
interface extending Iterable<T>
that holds a default <T> stream()
method.
解决此问题的一个非常简单的方法是创建一个包含方法的Streamable<T>
接口扩展。Iterable<T>
default <T> stream()
interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
Now any of your Iterable<T>
s can be trivially made streamable just by declaring them implements Streamable<T>
instead of Iterable<T>
.
现在,您Iterable<T>
的任何s 都可以通过声明它们implements Streamable<T>
而不是Iterable<T>
.
回答by Grzegorz Piwowarek
If you happen to use Vavr(formerly known as Javaslang), this can be as easy as:
如果您碰巧使用 Vavr(以前称为 Javaslang),这可以很简单:
Iterable i = //...
Stream.ofAll(i);
回答by Alex
So as another answer mentioned Guava has support for this by using:
因此,正如另一个答案所提到的,番石榴通过使用以下方法对此提供支持:
Streams.stream(iterable);
I want to highlight that the implementation does something slightly different than other answers suggested. If the Iterable
is of type Collection
they cast it.
我想强调的是,该实现与建议的其他答案略有不同。如果Iterable
是类型,Collection
他们会投射它。
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
);
}
回答by Greg Witczak
Another way to do it, with Java 8 and without external libs:
另一种方法,使用 Java 8 而没有外部库:
Stream.concat(collectionA.stream(), collectionB.stream())
.collect(Collectors.toList())