2 回答
TA贡献1820条经验 获得超10个赞
假设您对稍微不太方便的形式感到满意
import com.google.common.base.Equivalence;
...
metaData.add(new MetaData(Person.class, Equivalence.equals(), "name", "John", "group", "SIGMA"));
最简单的基于 Java 的解决方案是将内省实例的类添加到元数据中,参数化比较对象的方式(我在这里使用了 Guava,你也可以使用普通的 Java 8 BiPredicate<T super Person>)并指定属性的名称。
执行时,您可以利用它java.beans.Introspector#getBeanInfo()来发现 getter 和 setter 名称(这是克服各种 Java Beans 怪胎的最安全方法,例如布尔属性、完全大写的属性名称等。 - 我建议更喜欢它而不是基于字符串替换的半生不熟的工具)并相应地调用它们。
您可以使用以下方法进一步缩短通话时间
metaData.add(new MetaData<Person>(Equivalence.equals(), "name", "John", "group", "SIGMA"));
(类可以使用称为类型标记或类型文字的反射黑客派生)
或创建自己的子类,例如EqualsMetadataor PersonMetadata,您就明白了。
或者,您可以完全避免(普通的)反射并使用方法引用定义所有内容:
metaData.add(new MetaData(Equivalence.equals(), Person::getName, Person::setName, "John", Person::getGroup, Person::setGroup, "SIGMA"));
它更长但类型更安全 - 您可以确保参数John并SIGMA与 getter 和 setter 类型相对应。
要使用外部工具实现它,我建议查看 mapstruct.org。Dozer 也是可能的,但是在我们的项目中,由于基于生成代码的性能和哲学,我们迁移到 mapstruct,恕我直言,它可以更好地了解转换过程中真正发生的情况。
TA贡献1802条经验 获得超4个赞
主要有以下三个坑:
首先,您需要某种从字段名称到 getter/setter 方法的映射,以从 POJO 模型类访问字段值。
其次,各个字段的数据类型不同。因此,如果字段值没有实现,您需要一个不同的比较器
Comparable。你使用的类型实现了Comparable,所以你很好。第三,Java 不能
Object以泛型的方式来转换内置值类型;即 getter 方法的签名通常不匹配。您已经通过为诸如 int 之类的琐碎数据类型选择盒装类型来避免这种情况。
要使所有这些工作正常运行,您需要执行以下步骤:
因此,在第一步中,您需要构建一个 getter 方法的存储库。即类似的东西
HashMap<String, Function<Person, Object>> map1。您可以通过map1.put("name", Person::getName)或通过反射显式添加所有 getter 来静态执行此操作。接下来,您需要为 setter 构建一个存储库。即类似的东西
HashMap<String, BiConsumer<Person, Object>> map2。同样,您可以使用反射或显式初始化。在后一种情况下,还有另一个陷阱,因为 setter 的泛型类型转换不再是协变的。这可以通过双重未经检查的强制转换来处理:map2.put("name", (BiConsumer)(BiConsumer<Person, String>)Person::setName);由于 Java 的类型擦除,所有 setter 实际上都具有相同的匹配方法签名。
假设您的所有值类型都实现
Comparable了下一步是非常简单的。
调用您的getter从存储库,比较值(注意空的),并应用所需要的比较操作符(= 0,< 0,> 0或其他) -顺便说一句:你真的应该使用enum的MetaData::comparator,而不是字符串。如果需要,通过从存储库调用 setter 来分配结果值。
如果您不需要字符串作为字段名称的键,您可以加入步骤 1 和步骤 2。只需使用 getter 方法引用作为(强类型)键而不是名称。现在您只需要一个从 getter 映射到 setter 的存储库。IE:
HashMap<Function<Person, Object>, BiConsumer<Person, Object>> map;
这从 getter(用作键)映射到匹配的 setter 方法。
如果需要,我更喜欢这种方式,因为强类型值不易出错且重构更安全。
添加回答
举报
