Ale*_*nko 2 java lambda java-8 functional-interface method-reference
假设我们的方法接收输入 String并返回一些List output。此输出是一些生成器的结果,其中一些生成器取决于输入,而有些则不取决于输入-它们只是添加预定义的值。我想将这些生成器实现为一些函数接口的列表(例如,Consumer),然后将它们组合到一个Consumer中,然后将其应用于输入String。
因此,我将能够轻松,独立地更换小型发电机。但是问题在于,并非我的所有生成器都需要输入 String作为参数,而我只是出于一个原因就将这个参数传递给了它-能够将此类使用者与其他使用者组合在一起。
public class ConsumersTest {
private static <T, U> BiConsumer<T, U> combine(List<BiConsumer<T, U>> consumers) {
return consumers.stream().reduce((arg1, arg2) -> {}, BiConsumer::andThen);
}
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
combine(getGenerators()).accept(input, output);
return output;
}
private List<BiConsumer<String, List<String>>> getGenerators() {
return Arrays.asList(
this::addFirstDependent,
this::addSecondIndependent
);
}
private void addFirstDependent(String input, List<String> output) {
if (input.contains("some string")) {
output.add("First-Dependent");
}
}
private void addSecondIndependent(String input, List<String> output) {
output.add("Predefined Output");
}}
Run Code Online (Sandbox Code Playgroud)
是否可以将不同的消费者合并到一个保护伞下并在一个地方应用?还是这是一个坏主意,而不是正确的方法?
在模块化软件和适配器中具有通用接口以适合特定的实现并非不寻常的模式。例如
public class ConsumersTest {
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
generators.accept(input, output);
return output;
}
private static <T, U> BiConsumer<T, U> ignoreFirstArg(Consumer<U> consumer) {
return (t, u) -> consumer.accept(u);
}
private final BiConsumer<String, List<String>> generators =
Stream.<BiConsumer<String, List<String>>>of(
this::addFirstDependent,
ignoreFirstArg(this::addSecondIndependent)
).reduce(BiConsumer::andThen).orElse((arg1, arg2) -> {});
private void addFirstDependent(String input, List<String> output) {
if (input.contains("some string")) {
output.add("First-Dependent");
}
}
private void addSecondIndependent(List<String> output) {
output.add("Predefined Output");
}
}
Run Code Online (Sandbox Code Playgroud)
所以ignoreFirstArg是不具有第一个参数方法的一般适配器。可以有任意数量的适配器方法。但是请注意,如果适配器是非常特定的,因此仅使用一次,那么也可以在组合代码中编写lambda表达式而不是方法引用。请注意,我更改了代码,以免每次generate(String input)调用都被重复评估,否则,当您不重用组合函数时,将它们合并就没有意义了,因为您也可以使用
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
Stream.<BiConsumer<String, List<String>>>of(
this::addFirstDependent,
ignoreFirstArg(this::addSecondIndependent)
).forEach(g -> g.accept(input, output));
return output;
}
Run Code Online (Sandbox Code Playgroud)
甚至更简单
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
this.addFirstDependent(input, output);
this.addSecondIndependent(output);
return output;
}
Run Code Online (Sandbox Code Playgroud)
维护起来并不比功能代码差,因为每个生成器仍然由一行组成。
| 归档时间: |
|
| 查看次数: |
73 次 |
| 最近记录: |