5.7 KiB
5.7 KiB
我的公众号
Java_ConstractUtil
通用的Java同类型对象对比工具类,用于比较两个同类型对象的属性差异,并返回变化的部分。
快速开始
Maven依赖
<dependency>
<groupId>Java_ConstractUtil</groupId>
<artifactId>Java_ConstractUtil</artifactId>
<version>1.0.0</version>
</dependency>
基本使用
// 比较两个同类型对象
SimpleObj origin = new SimpleObj();
origin.setX(1);
origin.setY("hello");
SimpleObj target = new SimpleObj();
target.setX(2);
target.setY("hello");
ContrastObject<SimpleObj> result = ContrastUtil.contrast(origin, target);
if (result != null) {
// result.getOriginChange() -> 原始对象中发生变化的属性 (x=1)
// result.getTargetChange() -> 修改后对象中发生变化的属性 (x=2)
System.out.println(result.getOriginChange().getX()); // 1
System.out.println(result.getTargetChange().getX()); // 2
}
工具说明
ContrastUtil(通用对比工具)
ContrastUtil 是默认的对象对比实现类,提供静态方法 contrast(T origin, T target) 进行对象对比。
处理规则:
- 基本类型和包装类型:直接使用
equals进行比较(如int、String、Date等) - Collection类型:比较两个集合的差异,返回差集。仅处理一层,泛型内的元素直接调用
equals比较 - Map类型:比较两个Map的差异,包括相同key的value比较和不同key的差异
- 自定义类型:调用
equals方法进行比较,要求重写equals和hashCode方法,否则会比较对象地址 - 类型一致性:比较的两个对象类型必须一致,否则抛出
TypeMisMatchException - 空值处理:入参可以为
null,两者都为null返回null,其中一个为null则返回非空一方的结果 - Getter/Setter检查:自定义类型必须有完整的
get/set方法,否则抛出NoGetMethodException/NoSetMethodException - 抽象类和接口:不支持抽象类和接口的实例对比,会直接返回
null
返回值说明:
ContrastObject<T> 包含四个字段:
origin:原始对象(完整)target:修改后的对象(完整)originChange:原始对象中发生变化的属性(新实例,仅包含变化的字段)targetChange:修改后对象中发生变化的属性(新实例,仅包含变化的字段)
无变化时返回 null。
AbstractContrastUtil(抽象基类)
AbstractContrastUtil<T> 提供最大的自定义性,使用者可以通过继承并实现抽象方法来定制各种类型的对比逻辑。
需要实现的抽象方法:
| 方法 | 说明 |
|---|---|
originContract() |
基本类型和包装类型的对比逻辑 |
selfContract() |
自定义类型的对比逻辑 |
mapContract() |
Map类型的对比逻辑 |
collectionContract() |
Collection类型的对比逻辑 |
specialContract() |
特殊类型的自定义处理逻辑 |
isSpecialType() |
判断是否为特殊类型(优先于Collection/Map判断) |
nullProcessor() |
入参为null的处理逻辑 |
originProcessor() |
基本类型入参的处理逻辑 |
setContrastObject() |
组装返回结果对象 |
使用示例: 参考 ContrastUtilExample.java
项目结构
src/main/java/
├── ContrastUtil.java # 默认对比工具实现
├── AbstractContrastUtil.java # 抽象对比基类
├── ContrastUtilExample.java # 抽象基类使用示例
├── bean/
│ └── ContrastObject.java # 对比结果包装类
├── constant/
│ └── Constant.java # 常量定义
├── exception/
│ ├── NoGetMethodException.java # 缺少getter方法异常
│ ├── NoSetMethodException.java # 缺少setter方法异常
│ └── TypeMisMatchException.java # 类型不匹配异常
├── handler/
│ ├── CollectionHandler.java # Collection类型处理器
│ ├── MapHandler.java # Map类型处理器
│ ├── OriginHandler.java # 基本类型处理器
│ └── SelfHandler.java # 自定义类型处理器
└── util/
├── CheckUtil.java # 类型检查工具
├── ClassUtil.java # 类反射工具
├── CollectionUtil.java # 集合差异计算工具
├── MapUtil.java # Map工具
└── SetUtil.java # Set工具
依赖
| 依赖 | 版本 | 用途 |
|---|---|---|
| commons-lang3 | 3.9 | 通用工具 |
| commons-collections4 | 4.4 | 集合工具 |
| guava | 28.2-jre | Google工具库 |
| reflectasm | 1.11.0 | 高性能反射 |
注意事项
- Collection和Map仅处理一层,嵌套的泛型类型直接调用
equals比较,可能导致结果不准确。如需深度对比,请使用AbstractContrastUtil自定义处理逻辑 - 自定义类型必须重写
equals和hashCode方法,否则会比较对象地址而非值 - 当前使用 reflectASM 进行反射调用,性能优于标准反射,但仍有优化空间
- 暂不支持
is前缀的 boolean getter 方法(如isActive()),后续版本会支持
更新日志
- 2020/4/30:创建项目,完成初始实现和单元测试
- 2020/5/9:添加测试方法,修复反射处理null的空指针问题,创建抽象类和继承使用示例
- 2026/5/17:修复多个bug(MapHandler参数错误、OriginHandler空值比较逻辑、ContrastObject NPE风险等),优化代码实现,补全注释和文档
