对比

转载
发现一个小技巧,记录一下

写在前面

在工作中,我们经常会遇到这样的需求——比较两个对象是否相等,如果不相等的话,取出不相等的字段。
以下这些场景都需要我们对一个对象进行比较:

数据比对
做单元测试断言对象是否相等
前端要求对不相等的字段进行高亮显示

这种需求其实是非常简单的,但是如何优雅地解决这一类需求呢?
通常的做法是重写对象的 equals 方法。但是重写 equals 方法有很多缺点,例如:

每次对象属性有变更,一定要记得再重写(放心,你一定会忘记的)
每个对象只能有一个 equals 方法,但是可能你会需要不同的比对规则
只能对比两个对象是否相等,无法具体知道哪个属性不等
自动生成的 equals 方法无法基于 getter 方法进行比对
对象来自第三方依赖,无法重写 equals 方法

因此,实现一个通用的比对器可以减少很多不必要的麻烦,帮助我们很好地完成这一类的需求。

缘起

我是在做数据同步的时候有这个需求,我要将数据库的数据通过一定的规则导入到 ES 中,导入完成之后,如何比对两边的数据是否一致呢?这时候一个好用的比对器就是我非常好的帮手。
另外,我在做单元测试的时候发现,经常会需要将被测方法的返回值和期望的结果做 assertEquals 断言这时这个比对器也非常有帮助。我发现很多同事经常会遇到类似的需求。
于是,我找时间自己实现了一下。

实现

使用反射对传入的对象进行比对,提供了基于字段的比较器和基于 Getter 方法的对比器,并且充分考虑扩展性,使用者可以重写字段的比对规则。功能相对简单,代码实现也不难,而且做了很多注释,具体实现可以直接查看源码。
项目地址:https://github.com/dadiyang/equator
UML图:

使用方法

因为已经上传到了 maven 仓库中,我们使用非常方便:

  1. 添加 maven 依赖
<dependency>
    <groupId>com.github.dadiyang</groupId>
    <artifactId>equator</artifactId>
    <version>1.0.1</version>
</dependency>

  1. 初始化并调用方法
Equator equator = new GetterBaseEquator();
User user1 = new User(...);
User user2 = new User(...);
// 判断属性是否完全相等
equator.isEquals(user1, user2);
// 获取不同的属性
List<FieldInfo> diff = equator.getDiffFields(user1, user2);

扩展

/**
 * 日期在数据库不保存毫秒数,因此需要特殊处理,比对时间时,忽略毫秒数
 *
 * @author dadiyang
 * @date 2019/3/23
 */
public class MmInsensitiveEquator extends GetterBaseEquator {
    @Override
    protected boolean isFieldEquals(FieldInfo fieldInfo) {
        if (fieldInfo.getFirstVal() instanceof Date) {
            Date first = (Date) fieldInfo.getFirstVal();
            Date second = (Date) fieldInfo.getSecondVal();
            if (Objects.equals(first, second)) {
                return true;
            }
            // 忽略毫秒数
            return Objects.equals(Math.round(first.getTime() / 1000), Math.round(second.getTime() / 1000));
        }
        return super.isFieldEquals(fieldInfo);
    }
}

使用后记

这个技巧是转载的
第一次使用
首先如果是一个表可以直接引用
如果是两个表结构相同的表可以用BeanUtils.copyProperties(表1, 表2)
顺便再记一下,是把表一的数据复制到表2中;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值