说说在 Java 中如何比较两个对象

Common Lang 中的 Builder 包内提供了一个 DiffBuilder 类,可以比较两个对象,并返回不同的部分。

  1. 首先在要比较对象的类中实现 Diffable 接口,然后实现 DiffResult diff(T obj) 方法。
  2. 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 初始化代码,或者尝试用反射来优化这部分代码。

参考资料

commons.apache.org/proper/comm…

猜你喜欢

转载自juejin.im/post/7033394535736541198