根据SE 8 Stream.map()的Javadocs,该方法执行以下操作:
返回一个流,其中包含将给定函数应用于此流元素的结果。
然而,在一本我正在阅读的网络编程书籍(《使用Java学习网络编程》,Richard M. Reese)中,对一个回声服务器实现了大致以下代码片段。
这是一种实现将用户输入打印到套接字输入流的功能性方法。它按预期工作,但我不太理解它的原理。是因为map知道流是无限的,所以它会在新的流令牌可用时惰性执行吗?似乎在map迭代的同时向集合中添加东西有点黑魔法。请有人帮我理解背后发生了什么。
以下是我重新表述内容以避免混淆的map使用方式。我认为作者试图避免无限循环,因为你无法跳出forEach。
返回一个流,其中包含将给定函数应用于此流元素的结果。
然而,在一本我正在阅读的网络编程书籍(《使用Java学习网络编程》,Richard M. Reese)中,对一个回声服务器实现了大致以下代码片段。
Supplier<String> inputLine = () -> {
try {
return br.readLine();
} catch(IOException e) {
e.printStackTrace();
return null;
}
};
Stream.generate(inputLine).map((msg) -> {
System.out.println("Recieved: " + (msg == null ? "end of stream" : msg));
out.println("echo: " + msg);
return msg;
}).allMatch((msg) -> msg != null);
这是一种实现将用户输入打印到套接字输入流的功能性方法。它按预期工作,但我不太理解它的原理。是因为map知道流是无限的,所以它会在新的流令牌可用时惰性执行吗?似乎在map迭代的同时向集合中添加东西有点黑魔法。请有人帮我理解背后发生了什么。
以下是我重新表述内容以避免混淆的map使用方式。我认为作者试图避免无限循环,因为你无法跳出forEach。
Stream.generate(inputLine).allMatch((msg) -> {
boolean alive = msg != null;
System.out.println("Recieved: " + (alive ? msg : "end of stream"));
out.println("echo: " + msg);
return alive;
});
map
中使用副作用有点令人不适。 - RealSkeptic.takeWhile(Objects::nonNull).forEach(...)
而不是使用filter
。(尽管一般来说,我同意Andy的看法,使用循环更好。) - Radiodef