Java 组合具有不同参数或不同参数编号的使用者
比方说,我们的方法接收输入字符串并返回一些列表输出。这个输出是一些生成器的结果,其中一些依赖于输入,而另一些则不依赖输入——它们只是添加预定义的值。 我想将这些生成器实现为一些函数接口的列表(例如使用者),然后将它们组合成一个使用者,并将其应用于输入字符串 因此,我将能够轻松、独立地更换小型发电机。但问题是,并非我的所有生成器都需要输入字符串作为参数,我只是出于一个原因将此参数传递到那里——我有能力将此类消费者与其他消费者结合起来Java 组合具有不同参数或不同参数编号的使用者,java,lambda,java-8,method-reference,functional-interface,Java,Lambda,Java 8,Method Reference,Functional Interface,比方说,我们的方法接收输入字符串并返回一些列表输出。这个输出是一些生成器的结果,其中一些依赖于输入,而另一些则不依赖输入——它们只是添加预定义的值。 我想将这些生成器实现为一些函数接口的列表(例如使用者),然后将它们组合成一个使用者,并将其应用于输入字符串 因此,我将能够轻松、独立地更换小型发电机。但问题是,并非我的所有生成器都需要输入字符串作为参数,我只是出于一个原因将此参数传递到那里——我有能力将此类消费者与其他消费者结合起来 public class ConsumersTest { pr
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");
}}
公共类消费者测试{
专用静态双消费者联合收割机(列出消费者){
返回consumers.stream().reduce((arg1,arg2)->{},BiConsumer::then);
}
列表生成(字符串输入){
ArrayList输出=新的ArrayList();
合并(getGenerators())。接受(输入、输出);
返回输出;
}
私有列表getGenerators(){
返回数组.asList(
这取决于,
这是独立的
);
}
私有void addFirstDependent(字符串输入、列表输出){
if(input.contains(“某些字符串”)){
输出。添加(“第一依赖”);
}
}
私有void addSecondIndependent(字符串输入,列表输出){
输出。添加(“预定义输出”);
}}
是否有可能将不同的消费者组合在一个保护伞下,并将其应用于一个地方?或者这是一个坏主意,而且不是做这些事情的正确方法?在模块化软件和适配器中使用公共接口,以使特定的实现适合,这种模式并不少见。例如
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");
}
}
甚至更简单
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
this.addFirstDependent(input, output);
this.addSecondIndependent(output);
return output;
}
列表生成(字符串输入){
ArrayList输出=新的ArrayList();
此.addFirstDependent(输入、输出);
这个.addSecondIndependent(输出);
返回输出;
}
这并不比功能代码更糟糕,因为每个生成器都由一行代码组成。这是不是一个好主意,我不能说。但您似乎希望能够根据参数编号和类型对您的消费者进行分类,然后正确地向这些消费者提供信息。对于上面描述的简单情况,您可能需要构建两个列表,一个用于两个参数相关的使用者,另一个用于单参数独立的使用者。然后对它们进行相应的评估,并结合最终结果。是的,我考虑过这样的解决方案,但另一个问题-我需要这些消费者按照严格的顺序进行应用,比如FirstDependent->SecondIndependent->ThirdIndependent->FourthDeendent等等。嗯,似乎我以前也遇到过同样的问题,我没有传递
字符串
(在我的例子中,我不止一个参数),而是构建一个上下文
。。。对于需要一些参数的Consumer
,我将使用Consumer.withAge(12).withName(“Eugene”)
等来构建它,对于另一种类型Consumer.empty()
,这样一个消费者的所有getter
都将抛出异常。。。它可能只是隐藏了问题,但至少有人阅读和实现代码会理解发生了什么。当每个“消费者”实际产生单个(可选)值时,接收列表作为参数似乎有问题,因此它要么是供应商,要么是函数。此外,每次调用generate(String input)
时,执行整个combine(getGenerators())
操作都是浪费资源。Eugene,是的,我也尝试过这种方法。但这只是隐藏未使用的论点。现在,我正在寻找更好的方法来实现这一点。关于适配器的好主意!谢谢回答得很好,谢谢你的重复评价。实际上,我已经用类似的方法解决了这个问题,但是只使用了Consumer而不是BiConsumer和Consumer。因此,我将依赖消费者添加到列表中,作为addFirstDependentGenerator(字符串输入)等其他方法的结果。所以,我并没有忽略未使用的参数,而是只在需要的生成器中使用它。但是,是的,现在为了生成一个完整的列表,我需要传递输入参数。所以,我想,我应该使用你的选项,避免每次都创建一个列表。
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
this.addFirstDependent(input, output);
this.addSecondIndependent(output);
return output;
}