roi*_*oim 254 java iterable java-8 java-stream
在Java 8中,我们有Stream <T>类,它奇怪地有一个方法
Iterator<T> iterator()
Run Code Online (Sandbox Code Playgroud)
所以你会期望它实现接口Iterable <T>,这需要完全这个方法,但事实并非如此.
当我想使用foreach循环遍历Stream时,我必须做类似的事情
public static Iterable<T> getIterable(Stream<T> s) {
return new Iterable<T> {
@Override
public Iterator<T> iterator() {
return s.iterator();
}
};
}
for (T element : getIterable(s)) { ... }
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么吗?
ken*_*ytm 189
已经有人在邮件列表上问过同样的问题 ☺.主要原因是Iterable也有一个可重复的语义,而Stream则没有.
我认为主要原因是它
Iterable意味着可重用性,而Stream只能使用一次 - 更像是一种Iterator.如果
Stream扩展了,Iterable那么现有的代码在收到第二次Iterable抛出的时候可能会感到惊讶.Exceptionfor (element : iterable)
Zho*_*gYu 153
要转换Stream到Iterable,你可以做
Stream<X> stream = null;
Iterable<X> iterable = stream::iterator
Run Code Online (Sandbox Code Playgroud)
要传递Stream给期望的方法Iterable,
void foo(Iterable<X> iterable)
Run Code Online (Sandbox Code Playgroud)
只是
foo(stream::iterator)
Run Code Online (Sandbox Code Playgroud)
但它可能看起来很有趣; 更明确一点可能会更好
foo( (Iterable<X>)stream::iterator );
Run Code Online (Sandbox Code Playgroud)
kennytm描述了为什么将a Stream作为一种处理是不安全的Iterable,而钟宇提供了一种允许使用Streamas 的解决方法Iterable,尽管是以不安全的方式.这是有可能得到两全其美:可再用Iterable从Stream满足所做出的一切保障Iterable规范.
注意:SomeType这里不是类型参数 - 您需要用适当的类型(例如String)替换它或使用反射
Stream<SomeType> stream = ...;
Iterable<SomeType> iterable = stream.collect(toList()):
Run Code Online (Sandbox Code Playgroud)
有一个主要缺点:
延迟迭代的好处将会丢失.如果您计划立即迭代当前线程中的所有值,则任何开销都可以忽略不计.但是,如果您计划仅部分迭代或在不同的线程中进行迭代,则此即时且完整的迭代可能会产生意想不到的后果.
当然,最大的优点是你可以重复使用Iterable,而(Iterable<SomeType>) stream::iterator只允许一次使用.如果接收代码将多次遍历集合,则这不仅是必要的,而且可能有益于性能.
您可以在for循环中使用流,如下所示:
Stream<T> stream = ...;
for (T x : (Iterable<T>) stream::iterator) {
...
}
Run Code Online (Sandbox Code Playgroud)
(这使用Java 8功能接口强制转换。)
(这在上面的一些评论中得到了介绍(例如Aleksandr Dubinsky,但是我想将其提出来以使其更清晰可见)。
| 归档时间: |
|
| 查看次数: |
34313 次 |
| 最近记录: |