修改值的Java框架/模式
我有一个客观的人修改值的Java框架/模式,java,java-8,expression,comparator,Java,Java 8,Expression,Comparator,我有一个客观的人 public class Person { private String name; private Integer age ; private String address; private String group; private String id; public Person(String name, Integer age, String address, String group, String id) {
public class Person {
private String name;
private Integer age ;
private String address;
private String group;
private String id;
public Person(String name, Integer age, String address, String group, String id) {
this.name = name;
this.age = age;
this.address = address;
this.group = group;
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", group='" + group + '\'' +
", id='" + id + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
public void setGroup(String group) {
this.group = group;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public String getAddress() {
return address;
}
public String getGroup() {
return group;
}
public String getId() {
return id;
}
}
元数据
public class MetaData {
private String fieldName;
private String comparator;
private String fieldValue;
private String newFieldName;
private String newFieldValue;
public MetaData(String fieldName, String comparator, String fieldValue, String newFieldName, String newFieldValue) {
this.fieldName = fieldName;
this.comparator = comparator;
this.fieldValue = fieldValue;
this.newFieldName = newFieldName;
this.newFieldValue = newFieldValue;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getComparator() {
return comparator;
}
public void setComparator(String comparator) {
this.comparator = comparator;
}
public String getFieldValue() {
return fieldValue;
}
public void setFieldValue(String fieldValue) {
this.fieldValue = fieldValue;
}
public String getNewFieldName() {
return newFieldName;
}
public void setNewFieldName(String newFieldName) {
this.newFieldName = newFieldName;
}
public String getNewFieldValue() {
return newFieldValue;
}
public void setNewFieldValue(String newFieldValue) {
this.newFieldValue = newFieldValue;
}
}
我得到一张名单。对于每个人,我都必须检查元数据(基于ID)
对于每个元数据,我必须查看要匹配的字段以及要重放的值
比如说
public class TestPersonModifier {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("John", 22, "London", "BETA", "ABC"));
personList.add(new Person("Mathew", 44, "Glasgow", "ALPHA", "XYZ"));
List<MetaData> metaData = new ArrayList<>();
metaData.add(new MetaData("name", "EQUALS", "John", "group", "SIGMA"));
metaData.add(new MetaData("name", "EQUALS", "Mathew", "address", "Singapore"));
//g
personList.forEach(p -> {
metaData.forEach(m -> {
if (m.getFieldName().equals("name")) {
if (m.getComparator().equals("EQUALS")) {
if (p.getName().equals(m.getFieldValue())) {
if (m.getNewFieldName().equals("group")) {
System.out.println(p.getId() + "::The group value changed from " + p.getGroup() + " to " + m.getNewFieldValue());
p.setGroup(m.getNewFieldValue());
}
if (m.getNewFieldName().equals("address")) {
System.out.println(p.getId() + "::The address value changed from " + p.getAddress() + " to " + m.getNewFieldValue());
p.setGroup(m.getNewFieldValue());
}
}
}
}
});
});
}
}
公共类TestPersonModifier{
公共静态void main(字符串[]args){
List personList=新建ArrayList();
添加(新人(“约翰”,22岁,“伦敦”,“贝塔”,“ABC”);
添加(新人物(“马修”,44,“格拉斯哥”,“阿尔法”,“XYZ”);
列表元数据=新的ArrayList();
添加(新的元数据(“名称”、“相等”、“约翰”、“组”、“西格玛”);
添加(新的元数据(“名称”、“相等”、“马修”、“地址”、“新加坡”);
//g
personList.forEach(p->{
metaData.forEach(m->{
if(m.getFieldName().equals(“name”)){
if(m.getComparator().equals(“equals”)){
如果(p.getName().equals(m.getFieldValue())){
if(m.getNewFieldName().equals(“组”)){
System.out.println(p.getId()+”::组值从“+p.getGroup()+”更改为“+m.getNewFieldValue());
p、 setGroup(m.getNewFieldValue());
}
if(m.getNewFieldName().equals(“地址”)){
System.out.println(p.getId()+”::地址值从“+p.getAddress()+”更改为“+m.getNewFieldValue());
p、 setGroup(m.getNewFieldValue());
}
}
}
}
});
});
}
}
如上所述,这将是非常笨拙的,因为将有更多的比较器运算符和更多的字段
是否有我可以使用的表达式语言框架、JAva库或任何开源框架,使其成为通用解决方案假设您对稍微不那么方便的形式感到满意
import com.google.common.base.Equivalence;
...
metaData.add(new MetaData(Person.class, Equivalence.equals(), "name", "John", "group", "SIGMA"));
最简单的基于Java的解决方案是将内省实例类添加到元数据中,参数化比较对象的方式(我在这里使用了Guava,您也可以使用纯Java 8BiPredicate
)并指定属性名称
执行时,您可以利用java.beans.Introspector#getBeanInfo()
来发现getter和setter名称(这是克服各种java bean怪癖的最安全的方法,例如布尔属性、完全大写的属性名等-我建议您更喜欢它,而不是基于半成品字符串替换的工具)并相应地调用它们
您可以使用
metaData.add(new MetaData<Person>(Equivalence.equals(), "name", "John", "group", "SIGMA"));
它更长,但类型更安全-您可以确保参数John
和SIGMA
与getter和setter类型相对应
要使用外部工具实现它,我建议查看mapstruct.org。Dozer也是可能的,但是在我们的项目中,由于基于生成代码的性能和原理,我们迁移到mapstruct,IMHO可以更好地了解转换过程中实际发生的情况。主要有三个陷阱:
- 首先,需要从字段名到getter/setter方法的某种映射,以便从POJO模型类访问字段值
- 其次,各个字段的数据类型不同。因此,如果字段值未实现
,则需要不同的比较器。您使用的类型实现了compariable
,因此您很好可比性
- 第三,Java不能以通用方式将内置值类型从
对象转换为
;i、 getter方法的签名通常不匹配。您已经通过为诸如int之类的普通数据类型选择装箱类型来避免了这种情况
HashMap map1
。您可以通过map1.put(“name”,Person::getName)
或通过反射显式添加所有getter来静态地实现这一点HashMap map2
。同样,您可以使用反射或显式初始化。在后一种情况下,还有另一个陷阱,因为setter的泛型类型转换不再是协变的。这可以通过双重未选中强制转换来处理:
map2.put("name", (BiConsumer)(BiConsumer<Person, String>)Person::setName);
这将从getter(用作键)映射到匹配的setter方法。如果需要的话,我更喜欢这种方式,因为强类型值不太容易出错,而且重构更安全。投票决定关闭问题的人应该注意发表评论。
map2.put("name", (BiConsumer)(BiConsumer<Person, String>)Person::setName);
HashMap<Function<Person, Object>, BiConsumer<Person, Object>> map;