Bas*_*que 24 java iterable java-stream
Stream
继承一个iterator()方法来生成一个Iterator
.
例如,给定这个字符串:
String input = "this\n" +
"that\n" +
"the_other";
Run Code Online (Sandbox Code Playgroud)
...我需要将字符串的这些部分作为 anIterable
传递给特定的库。调用input.lines()
产生一个Stream
. 所以如果我能把它Stream
变成Iterable
它的一个元素,我会很高兴的。
Hol*_*ger 28
正如为什么 Stream<T> 不实现 Iterable<T>?,aIterable
承担能够提供Iterator
不止一次的期望,而 aStream
无法实现。因此,虽然您可以为临时使用创建一个Iterable
out of a Stream
,但您必须小心是否可能存在多次迭代它的尝试。
既然您说“我需要将字符串的这些部分作为 anIterable
传递给特定的库”,那么没有通用的解决方案,因为使用 的代码Iterable
超出了您的控制范围。
但是,如果您是创建流的人,则可以创建一个有效的Iterable
,它会在每次Iterator
请求时简单地重复流构造:
Iterable<String> lines = () -> "this\nthat\nthe_other".lines().iterator();
Run Code Online (Sandbox Code Playgroud)
这满足了支持任意次数迭代的期望,同时在仅遍历一次时不会消耗比单个流更多的资源。
for(var s: lines) System.out.println(s);
lines.forEach(System.out::println);
System.out.println(String.join("\n", lines));
Run Code Online (Sandbox Code Playgroud)
只需投射,无需转换。
投射Stream<String>::iterator
到Iterable<String>
.
注意请参阅 Holger 的回答,解释使用流支持的Iterable
.
解决方案很简单,但并不明显。见这个职位上莫里斯·纳夫特尔林的lambda常见问题解答。
返回 aiterator
的BaseStream
(的超类Stream
)方法的签名Iterator
与函数接口的唯一方法匹配Iterable
,因此Stream<T>::iterator
可以将方法引用用作 的实例Iterable<T>
。(这两种方法的名称相同纯属巧合。)
进行输入。
String input = "this\n" +
"that\n" +
"the_other";
Stream<String> stream = input.lines() ;
Run Code Online (Sandbox Code Playgroud)
使用方法引用生成一个Iterable<String>
.
Iterable< String > iterable = stream::iterator;
Run Code Online (Sandbox Code Playgroud)
测试结果。
for ( String s : iterable )
{
System.out.println( "s = " + s );
}
Run Code Online (Sandbox Code Playgroud)
s = 这个
s = 那
s = the_other
CAVEAT注意流支持的风险Iterable
。Holger在正确答案中进行了解释。
归档时间: |
|
查看次数: |
8510 次 |
最近记录: |