英文:
Difference between map and forEach for instance modification
问题
当我运行下面的代码时,StringBuilder 实例保持为空。
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(param -> sb.append(param));
然而,当我运行相同的代码,但将 map 替换为 forEach 时,它按预期行为(将数组元素附加到 StringBuilder 实例):
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).forEach(param -> sb.append(param));
为什么第一个示例中的 StringBuilder 没有改变呢?
英文:
When I run the code below, StringBuilder instance remains empty.
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(param -> sb.append(param));
However, when I run the same code with forEach instead of map, it behaves as expected (appends array elements to StringBuilder instance):
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).forEach(param -> sb.append(param));
Why doesn't it change StringBuilder in the first example?
答案1
得分: 3
原因是流未被调用。
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(param -> sb.append(param));
最后一条语句不会执行,因为没有后续方法来激活流。尝试这样写:
Stream.of(params).map(param -> sb.append(param)).forEach(System.out::println);
现在 sb
应该包含了这些值。
英文:
The reason is that the stream has not been invoked.
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(param -> sb.append(param));
The last statement doesn't run since there is no subsequent method that activates the stream. Try this:
Stream.of(params).map(param -> sb.append(param)).forEach(System.out::println);
Now sb
should have the values.
答案2
得分: 1
Stream
s被惰性评估。这意味着诸如Stream::map
和Stream::filter
之类的中间操作只有在通过像Stream::forEach
或Stream::collect
这样的终端操作触发时才会被评估。
我们可以重写代码以使其按预期运行:
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(sb::append).collect(Collectors.toList());
System.out.println(sb.toString());
然而,我建议使用本帖中提供的forEach
示例,因为这样可以简洁明了地反映代码的语义。
英文:
Stream
s are evaluated lazily. This means that intermediate operations like Stream::map
and Stream::filter
are only evaluated when they are triggered through a terminal operation like Stream::forEach
or Stream::collect
.
We can rewrite the code to make it behave as expected:
String[] params = {"v1", "v2"};
StringBuilder sb = new StringBuilder();
Stream.of(params).map(sb::append).collect(Collectors.toList());
System.out.println(sb.toString());
I would, however, suggest to use the forEach
-example presented in the post, since this reflects the semantics of the code in a concise and clear way.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论