试验我的代码我想知道是否有任何方法可以“压缩”它(单线是最终目标)。
vanilla java:
public void setUsingSwitch(Field field, String value) {
switch (field) {
case FIRST_NAME:
setFirstName(value);
break;
case LAST_NAME:
setLastName(value);
break;
default:
throw new IndexOutOfBoundsException("Unknow field " + field);
}
}
“压缩”:
public void setUsingConsumer(Field field, String value) {
Consumer<String> setter = field == FIRST_NAME ? this::setFirstName : field == LAST_NAME ? this::setLastName : v -> {
throw new IndexOutOfBoundsException("Unknow field " + field);
};
setter.accept(value);
}
对于两种用途:
public static enum Field { FIRST_NAME, LAST_NAME }
void setFirstName(String value) { }
void setLastName(String value) { }
当然这对我来说只是科学上的兴趣,但有没有办法写出更小的代码?
答案 0 :(得分:4)
由于您发现实际上没有enum
,因此更通用的解决方案可能如下所示:
class Person {
public void setFirstName(String value) {
// …
}
public void setLastName(String value) {
// …
}
static final Map<String,BiConsumer<Person,String>> FIELDS;
static {
Map<String,BiConsumer<Person,String>> m=new HashMap<>();
m.put("FirstName", Person::setFirstName);
m.put("LastName", Person::setLastName);
FIELDS=Collections.unmodifiableMap(m);
}
public void setField(String field, String value) {
FIELDS.getOrDefault(field, (k,v)->{ throw new NoSuchElementException(); })
.accept(this, value);
}
}
顺便说一句,既然你说过“业务逻辑”,我建议如下:“Falsehoods Programmers Believe About Names”
答案 1 :(得分:3)
这是一种替代方法,它不短,但有时更可取:
import java.util.function.BiConsumer;
public class MyObj {
public static enum Field {
FIRST_NAME(MyObj::setFirstName),
LAST_NAME(MyObj::setLastName);
Field(BiConsumer<MyObj, String> setter) {
this.setter = setter;
}
final BiConsumer<MyObj, String> setter;
}
public void set(Field field, String value) {
field.setter.accept(this, value);
}
public void setFirstName(String s) {...}
public void setLastName(String s) {...}
}
答案 2 :(得分:1)
鉴于您的初始设计,我想您想要为 Person 枚举所有可能的设置器。此外,它接收就好像你要收集 Field 来设置和值,然后调用正确的setter。这是我的解决方案,保留了您的设计目标:
public enum Field {
FIRST_NAME {
public void setValue(String value, Person person) {
person.setFirstName(value);
}},
LAST_NAME {
public void setValue(String value, Person person) {
person.setLastName(value);
}};
public abstract void setValue(String value, Person person);
}
public class Person {
private String firstName;
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void clearUsingConsumer(Field field, String value) {
field.setValue(value, this);
}
}
答案 3 :(得分:0)
以下是Optional的结尾:
Field field = FIRST_NAME;
Optional.<Consumer<String>>ofNullable(
field == FIRST_NAME
? this::setFirstName
: field == LAST_NAME
? this::setLastName
: null).orElseThrow(IndexOutOfBoundsException::new)
.accept("John");
虽然我不确定将它写在一行是件好事。甚至使用它而不是简单的switch
。