将多个 if 语句转换为调度函数

Convert multiple if statements to dispatch functions

我正在努力寻找一种方法将其分派给 java8

中的函数
    Person p = registry.getPerson();

    if (field == Field.LASTNAME) {
        p.setLastName(str);
    }
    if (field == Field.FIRSTNAME) {
        p.setFirstName(str);
    }
    if (field == Field.MIDDLENAME) {
        p.setMiddleName(str);
    }

我的想法是在更多情况下使用某种函数调度table来替换if语句:

Map<Integer, Function> map = new HashMap<Integer, Function>  
static {
    map.put(1, new Function<String, String>() {
        @Override
        public Object apply(String str) {
            person.setLastName(str);
            return str;
        }
    }
}

但是代码无法编译,因为我需要将 person 对象传递到某个地方。有人知道这个的模式吗?

您可以存储 BiFunction<Person,String,String> 并将 Person 实例作为参数传入,而不是存储 Function<String,String>

Map<Integer, BiFunction<Person,String,String>> map = 
        new HashMap<Integer, BiFunction<Person,String,String>>();  
static {
    map.put(1, (person, str)->person.setLastName(str));

}

为了简单起见,您也可以只存储 List 个函数,如果您只是想用整数索引它们,随机访问速度更快,通用性更简单代码:

List<BiFunction<Person,String,String>> list = new ArrayList<BiFunction<Person,String,String>>();  
static {
    list.add((person, str)->person.setLastName(str));
}    

假设 Field 是枚举,您可以添加 BiConsumer<Person,String> 作为枚举字段:

class Person {

    static enum Field {
        FIRSTNAME(Person::setFirstName),
        MIDDLENAME(Person::setMiddleName),
        LASTNAME(Person::setLastName)
        ;

        private BiConsumer<Person, String> setter;

        private Field(BiConsumer<Person, String> setter) {
            this.setter = setter;
        }
    }

    public void set(Field field, String str) {
        field.setter.accept(this, str);
    }

    ......
}