Java 终端操作用于评估中间操作

Java 终端操作用于评估中间操作,java,java-8,java-stream,Java,Java 8,Java Stream,假设我有一个字符串列表,我想使用这些字符串作为fluent builder的输入 List<String> scripts; //initialize list ScriptRunnerBuilder scriptRunnerBuilder = new ScriptRunnerBuilder(); BiFunction<String,ScriptRunnerBuilder,ScriptRunnerBuilder> addScript = (script,build

假设我有一个字符串列表,我想使用这些字符串作为fluent builder的输入

List<String> scripts;

//initialize list

ScriptRunnerBuilder scriptRunnerBuilder = new ScriptRunnerBuilder();

BiFunction<String,ScriptRunnerBuilder,ScriptRunnerBuilder> addScript = 
(script,builder) -> builer.addScript(script);

scriptRunnerBuilder = scripts.stream.map(script -> 
addScript.apply(script,scriptRunnerBuilder)).......

scriptRunnerBuilder.build();
我可以使用哪个终端操作,以便为列表中的所有元素调用addScript函数


问题是ScriptRunnerBuilder是不可变的,ScriptRunnerBuilder.addScript将返回一个新的ScriptRunnerBuilder对象,而不是修改现有的对象,因此我不能只使用foreach

我的意图是携带addScript调用的结果,并将其用作流中下一个元素的输入

使用forEach而不是map,并且不再分配流的结果

scripts.forEach(script -> addScript.apply(script,scriptRunnerBuilder));
使用forEach而不是map,并且不再分配流的结果

scripts.forEach(script -> addScript.apply(script,scriptRunnerBuilder));

最简单的方法是:

// create your builder
ScriptRunnerBuilder builder = new ScriptRunnerBuilder();

// add all scripts
scripts.forEach(script-> builder.addScript(script))

build results
scriptRunnerBuilder.build();
因为生成器聚合了所有数据,并且您已经在forEach lambda外部创建了它,所以您可以直接访问它。这将导致更少的代码和相同的结果

或者正如@Holger所建议的:

scripts.forEach(builder::addScript);

最简单的方法是:

// create your builder
ScriptRunnerBuilder builder = new ScriptRunnerBuilder();

// add all scripts
scripts.forEach(script-> builder.addScript(script))

build results
scriptRunnerBuilder.build();
因为生成器聚合了所有数据,并且您已经在forEach lambda外部创建了它,所以您可以直接访问它。这将导致更少的代码和相同的结果

或者正如@Holger所建议的:

scripts.forEach(builder::addScript);
我可以使用reduce操作,但这是不必要的,因为我们没有合并结果

合并正是您正在做的事情。 您将所有脚本从列表合并到ScriptRunnerBuilder,是吗

我同意没有流的@Beri解决方案可能是最简单的。但还有一种方法,您不需要在之前创建ScriptRunnerBuilder:

请参阅更多:

更新为不依赖于顺序流未调用组合器的事实,并使其与并行流一起工作,您必须实现真正的组合器

如果可以添加重写的方法addScriptScriptRunnerBuilder otherBuilder,则reduce将如下所示:

.reduce(new ScriptRunnerBuilder(), ScriptRunnerBuilder::addScript, 
        ScriptRunnerBuilder::addScript)
我可以使用reduce操作,但这是不必要的,因为我们没有合并结果

合并正是您正在做的事情。 您将所有脚本从列表合并到ScriptRunnerBuilder,是吗

我同意没有流的@Beri解决方案可能是最简单的。但还有一种方法,您不需要在之前创建ScriptRunnerBuilder:

请参阅更多:

更新为不依赖于顺序流未调用组合器的事实,并使其与并行流一起工作,您必须实现真正的组合器

如果可以添加重写的方法addScriptScriptRunnerBuilder otherBuilder,则reduce将如下所示:

.reduce(new ScriptRunnerBuilder(), ScriptRunnerBuilder::addScript, 
        ScriptRunnerBuilder::addScript)

scripts.forEachscript->addScript.applyscript,scriptRunnerBuilder;是的,但是它必须返回吗?您有一个对生成器的引用。它不必返回任何内容。我知道我可以使用reduce操作,但这是不必要的,因为我们没有组合resultsscripts.forEachscript->addScript.applyscript、scriptRunnerBuilder;是的,但是它必须返回吗?您有一个对生成器的引用。它不必返回任何东西。我知道我可以使用reduce操作,但这是不必要的,因为我们没有组合结果,甚至没有脚本;问题在于ScriptRunnerBuilder是不可变的,因此ScriptRunnerBuilder.addScript返回一个新的ScriptRunnerBuilder对象,而不是修改existing@Claudiga然后使用一个普通循环,forString s:scripts builder=builder.addScripts@霍尔格:是的,这听起来是唯一干净的方法。我只是想看看如何使用Stream甚至脚本来完成;问题在于ScriptRunnerBuilder是不可变的,因此ScriptRunnerBuilder.addScript返回一个新的ScriptRunnerBuilder对象,而不是修改existing@Claudiga然后使用一个普通循环,forString s:scripts builder=builder.addScripts@霍尔格:是的,这听起来是唯一干净的方法。我只是想看看如何使用流来实现