底线是,在某种程度上,您需要将MyDto.getType()的可能返回值映射到MyBuilder的属性设置方法.您的代码通过switch语句执行此操作,这很好.您可以将缩减编写为基于流的管道,但您仍需要以某种方式合并映射.
一个非常直接的方法是构造一个文字Map,它可以是静态的,最终的和不可修改的.例如,如果您从类似结构的类开始…
class Some {
}
class MyBuilder {
void field1(String s) { }
void field2(String s) { }
void field3(String s) { }
Some build() {
return null;
}
}
class ValueType {}
class MyDto {
int type;
ValueType value;
int getType() {
return type;
}
ValueType getValue() {
return value;
}
}
…那么你可以设置你所描述的减少:
public class Reduction {
// Map from DTO types to builder methods
private final static Map> builderMethods;
static {
// one-time map initialization
Map> temp = new HashMap<>();
temp.put(FIELD1, MyBuilder::field1);
temp.put(FIELD2, MyBuilder::field2);
temp.put(FIELD3, MyBuilder::field3);
builderMethods = Collections.unmodifiableMap(temp);
}
public Some reduce(Collection col) {
return col.stream()
// this reduction produces the populated builder
.reduce(new MyBuilder(),
(b, d) -> { builderMethods.get(d.getType()).accept(b, d); return b; })
// obtain the built object
.build();
}
}
该特定实现每次都使用一个新的构建器,但是可以修改为使用通过参数传递给Reduction.reduce()的构建器,以防您想要预先填充一些属性,和/或保留记录用于构建返回对象的属性.
最后,请注意尽管您可以在一个地方或另一个地方隐藏详细信息,但我没有看到任何范围使整个过程比您开始使用的基于交换机的代码更简单.