在Java中如何比较两个对象浅析
Common Lang 中的 Builder 包内提供了一个 DiffBuilder 类,可以比较两个对象,并返回不同的部分。
- 首先在要比较对象的类中实现 Diffable 接口,然后实现 DiffResult diff(T obj) 方法。
- 在DiffResult diff(T obj) 方法中,新建一个 DiffBuilder 对象,把需要比较的类属性一一放入 DiffBuilder 中。
DiffBuilder 的构造函数有三个入参,lhs 是当前对象,rhs 是要比较的对象,style 是比较结果输出的格式。
DiffBuilder(final T lhs, final T rhs,
final ToStringStyle style)
假设有一个 Person 类定义了三个属性 name、age 和 smoker。以下是使用不同的 ToStringStyle 所对应的输出内容。
| ToStringStyle | 说明 | 输出 |
|---|---|---|
| SHORT_PREFIX_STYLE | 简短 | Person[name=deniro,smoker=false] differs from Person[name=jack,smoker=true] |
| DEFAULT_STYLE | 默认 | org.apache.commons.lang3.builder.Person@9f70c54[name=deniro,smoker=false] differs from org.apache.commons.lang3.builder.Person@234bef66[name=jack,smoker=true]。 |
| MULTI_LINE_STYLE | 多行 | org.apache.commons.lang3.builder.Person@9f70c54[ name=deniro smoker=false ] differs from org.apache.commons.lang3.builder.Person@234bef66[ name=jack smoker=true ] |
| NO_FIELD_NAMES_STYLE | 不包含类属性名 | org.apache.commons.lang3.builder.Person@9f70c54[deniro,false] differs from org.apache.commons.lang3.builder.Person@234bef66[jack,true]。 |
| SIMPLE_STYLE | 简洁 | deniro,false differs from jack,true。 |
| NO_CLASS_NAME_STYLE | 不包含类名 | [name=deniro,smoker=false] differs from [name=jack,smoker=true]。 |
| JSON_STYLE | JSON | {"name":"deniro","smoker":false} differs from {"name":"jack","smoker":true}。 |
感觉 NO_CLASS_NAME_STYLE 与 JSON_STYLE 看的更清楚。
完整示例:
public class Person implements Diffable<Person> {
private static final Logger log = LoggerFactory.getLogger(Person.class);
String name;
int age;
boolean smoker;
public DiffResult diff(Person obj) {
// No need for null check, as NullPointerException correct if obj is null
return new DiffBuilder(this, obj, ToStringStyle.SHORT_PREFIX_STYLE)
.append("name", this.name, obj.name)
.append("age", this.age, obj.age)
.append("smoker", this.smoker, obj.smoker)
.build();
}
public static void main(String[] args) {
Person a = new Person();
a.name = "deniro";
a.age = 22;
a.smoker = false;
Person b = new Person();
b.name = "jack";
b.age = 22;
b.smoker = true;
DiffResult result = a.diff(b);
log.info("result -> {}。", result);
}
}
输出:
result -> Person[name=deniro,smoker=false] differs from Person[name=jack,smoker=true]。
如果是个大类,那么需要很多个 append 方法把这个大类的属性放到 DiffBuilder 中,不太方便。可以写个程序生成 DiffBuilder 初始化代码,或者尝试用反射来优化这部分代码。
反射扩展:
(1)获取对象所属类的Class方法。
Class c = Class.forName("包.类名称");
(2)获得该类的所有Filed(不包括父类)。
Field[] fields = c.getDeclaredFields();
(3)将所有属性的访问权限设为true。
因为JavaBean中所有的属性访问权限都是private,所以无法直接获得所有属性,因此我们必须获得其访问权限,通过下面的方法完成:
setAccessible(true);
(4)输出对象属性
f.getField(对象名称);
(5)获取字段名
fields[j].getName()
(6)获取字段值
fields[j].get(obj)
参考资料
commons.apache.org/proper/comm…
总结
到此这篇关于在Java中如何比较两个对象的文章就介绍到这了,更多相关Java比较两个对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java synchronized同步静态方法和同步非静态方法的异同
这篇文章主要介绍了java synchronized同步静态方法和同步非静态方法的异同的相关资料,需要的朋友可以参考下2017-01-01
使用spring.profiles.active来分区配置的方法示例
这篇文章主要介绍了使用spring.profiles.active来分区配置的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-01-01
SpringBoot整合Spring Security过滤器链加载执行流程源码分析(最新推荐)
Spring Boot 对于 Spring Security 提供了自动化配置方案,可以使用更少的配置来使用 Spring Security,这篇文章主要介绍了SpringBoot整合Spring Security过滤器链加载执行流程源码分析,需要的朋友可以参考下2023-02-02
Java @Value("${xxx}")取properties时中文乱码的解决
这篇文章主要介绍了Java @Value("${xxx}")取properties时中文乱码的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-07-07


最新评论