Java 如何访问forEach内部lambda之外的对象?
我有以下代码:Java 如何访问forEach内部lambda之外的对象?,java,lambda,Java,Lambda,我有以下代码: String fields = ""; listofObjects.stream().forEach(l -> fields = fields + l.text); 这不起作用,因为字段应该是最终字段。如何使用lambdas修改字段?实现该功能的最小更改就是使用StringBuilder,这将更有效: StringBuilder builder = new StringBuilder(); listofObjects.stream().forEach(l -> bu
String fields = "";
listofObjects.stream().forEach(l -> fields = fields + l.text);
这不起作用,因为
字段
应该是最终字段。如何使用lambdas修改字段
?实现该功能的最小更改就是使用StringBuilder
,这将更有效:
StringBuilder builder = new StringBuilder();
listofObjects.stream().forEach(l -> builder.append(l.text));
String fields = builder.toString();
正如Martin所指出的,
Collectors.joining()
提供了一般的字符串连接功能,但您需要首先将对象流映射到字符串流。(使用map
很容易,如果您经常需要这样做,您可以创建自己的收集器来完成。)流和lambda通常应该是无状态的。以下是针对您的案例的常规解决方案:
String fields = listofObjects.stream()
.map(l -> l.text)
.collect(Collectors.joining());
如果您需要执行完全相同的操作:
StringBuilder builder = new StringBuilder();
listofObjects.stream().forEach(l -> builder.append(l.text));
但更实用的方法是
fields = listofObjects.stream().map(l -> l.text).collect(Collectors.joining());
我们可以使用:
或者,根据@shmosel的以下评论:
String fields = listofObjects.stream()
.reduce("", String::concat);
您可以执行对象列表。forEach无需
.stream()
始终记住,流lambda可以并行执行-这就是Java保护您不被意外覆盖非最终属性或的原因。reduce(“,String::concat”)代码>。但是,当有一个更高效的收集器用于此目的时,为什么要使用reduce()
。@shmosel-true,reduce有另一个重载版本,它接受一个可以使用的初始值。我不认为这样做有任何附加价值,也不认为你提供的解决方案有任何附加价值。您是否看到其中一个函数有赞成/反对的地方?我建议的重载值是它不需要get()
调用,这通常应该避免。如果要使用可选
重载,至少要使用orElse(“”
)来反映OP的意图。收集器的价值在于它可以说更为惯用,因此也更为熟悉。另外,它在内部使用StringJoiner
,这避免了重复连接的成本。
String fields = listofObjects.stream()
.reduce("", String::concat);