Java 为对象创建公共生成器,而不考虑传入的字段

Java 为对象创建公共生成器,而不考虑传入的字段,java,java-8,builder,Java,Java 8,Builder,我有一个有多个字段的类: @Builder public class SampleClass { private String a; private String b; private String c; private String d; } 我有一个助手类,它可以修改字符串: public class StringModifier { public static String prefixUnderscore(String text) {

我有一个有多个字段的类:

@Builder
public class SampleClass {
    private String a;
    private String b;
    private String c;
    private String d;
}
我有一个助手类,它可以修改字符串:

public class StringModifier {
    public static String prefixUnderscore(String text) {
        return "_" + text;
    }

    public static String postfixUnderscore(String text) {
        return text + "_";
    }
}
现在,根据一些条件,我可能有字段a或字段b。要构建对象,我需要执行以下操作:

private static SampleClass getSampleClassWithB(String b, String c, Function<String, String> mapper) {
        String d = mapper.apply(b);
        return SampleClass.builder().b(b).c(c).d(d).build();
    }

    private static SampleClass getSampleClassWithA(String a, String c, Function<String, String> mapper) {
        String d = mapper.apply(a);
        return SampleClass.builder().a(a).c(c).d(d).build();
    }

现在您可以看到getSampleClassWithA和getSampleClassWithB做的事情非常相似。有没有一种方法可以将其组合成一种方法

与往常一样,如果两个或多个方法基本相同,并且您希望避免代码重复,那么您必须找到差异的抽象,在这种情况下,在生成器上调用
a
b

private static SampleClass getSampleClassWith(
    String value, BiFunction<SampleClassBuilder,String,SampleClassBuilder> property,
    String c, Function<String, String> mapper) {

    return property.apply(SampleClass.builder(),value).c(c).d(mapper.apply(value)).build();
}

你能解释一下双功能的工作顺序吗?property.apply实际上如何创建生成器,然后应用属性a或B生成器仍然是通过
SampleClass.builder()
创建的,该生成器作为参数传递给
apply
方法。在此上下文中,
SampleClassBuilder::a
相当于
(builder,arg)->builder.a(arg)
。由于调用者传递
SampleClass.builder()
的结果,并且函数返回
a(…)
的结果,因此结果与
SampleClass.builder().a(…)…
链的结果相同。
private static SampleClass getSampleClassWith(
    String value, BiFunction<SampleClassBuilder,String,SampleClassBuilder> property,
    String c, Function<String, String> mapper) {

    return property.apply(SampleClass.builder(),value).c(c).d(mapper.apply(value)).build();
}
getSampleClassWith("a", SampleClassBuilder::a, "c", StringModifier::postfixUnderscore);
getSampleClassWith("b", SampleClassBuilder::b, "c", StringModifier::prefixUnderscore);