我有一个返回的接口java.lang.Iterable<T>
。
我想使用Java 8 Stream API处理该结果。
但是Iterable无法“流式传输”。
任何想法如何将Iterable用作流而不转换为List?
myIterable.stream()
不存在!
Stream.of(iterable)
产生了Stream<Iterable<Object>>
。
我有一个返回的接口java.lang.Iterable<T>
。
我想使用Java 8 Stream API处理该结果。
但是Iterable无法“流式传输”。
任何想法如何将Iterable用作流而不转换为List?
myIterable.stream()
不存在!
Stream.of(iterable)
产生了Stream<Iterable<Object>>
。
Answers:
有一个比spliteratorUnknownSize
直接使用更好的答案,这既简单又得到更好的结果。 Iterable
有一个spliterator()
方法,所以您应该使用该方法来获取分离器。在最坏的情况下,它是相同的代码(默认实现使用spliteratorUnknownSize
),但是在更常见的情况下,您Iterable
已经是一个集合,您将获得更好的分离器,从而获得更好的流性能(甚至可能具有良好的并行性)。它的代码也更少:
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
如您所见,从中获取数据流Iterable
(另请参见此问题)并不是很痛苦。
Stream
会很好,例如Stream.ofIterable(iterable)
。
如果您可以使用Guava库(从21版开始),则可以使用
Streams.stream(iterable)
Lists.newArrayList(Iterable)
。
您可以轻松地Stream
从Iterable
或中创建一个Iterator
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
stream(...)
会使您的代码混乱?
因此,正如提到的另一个答案一样,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)。
如果您碰巧使用了Vavr(以前称为Javaslang),则可以像这样简单:
Iterable i = //...
Stream.ofAll(i);
使用Java 8并且没有外部库的另一种方法:
Stream.concat(collectionA.stream(), collectionB.stream())
.collect(Collectors.toList())