我有一个返回java.lang.Iterable<T>
的接口。
我想使用Java 8 Stream API操纵该结果。
然而,Iterable不能"stream"。
有没有办法在不将其转换为List的情况下将Iterable用作Stream?
我有一个返回java.lang.Iterable<T>
的接口。
我想使用Java 8 Stream API操纵该结果。
然而,Iterable不能"stream"。
有没有办法在不将其转换为List的情况下将Iterable用作Stream?
有比直接使用spliteratorUnknownSize
更好的解决方案,既更容易实现,又能获得更好的结果。 Iterable
具有spliterator()
方法,因此你应该使用它来获取你的spliterator。最坏的情况下,它是相同的代码(默认实现使用spliteratorUnknownSize
),但在更常见的情况下,如果你的Iterable
已经是一个集合,则会获得更好的spliterator,因此可以获得更好的流性能(甚至可能有良好的并行性)。而且,这还需要更少的代码:
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
正如您所看到的,从Iterable
获得一个流(也可以参见这个问题)并不困难。
Stream
上的静态方法会很不错,例如 Stream.ofIterable(iterable)
。 - robinst如果您可以使用Guava库,自版本21以来,您可以使用
Streams.stream(iterable)
Lists.newArrayList(Iterable)
。 - Jacob van Lingen您可以轻松地通过一个 Iterable
或 Iterator
创建一个 Stream
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
stream(...)
会让你的代码变得混乱呢? - gexicide我建议使用JOOL库,它将spliterator技术隐藏在Seq.seq(iterable)
调用后面,并提供了大量其他有用的功能。
正如其他回答提到的,Guava可以通过使用以下方式支持此功能:
Streams.stream(iterable);
我想强调的是,这个实现与其他答案提供的略有不同。如果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
);
}
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);
}
}
我认为这段代码非常易读,因为你不需要考虑分割器和布尔值(isParallel)。
Streamable<T>
接口,该接口扩展了 Iterable<T>
,并包含一个 default <T> stream()
方法。interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
implements Streamable<T>
而不是Iterable<T>
,轻松地使任何Iterable<T>
可流化。Iterable i = //...
Stream.ofAll(i);
myIterable.stream()
不存在! - Josh M.Stream.of(iterable)
会生成Stream<Iterable<Object>>
。 - Matthias Braun