(类比较器)java对比两个相同实体类中属性的值的差异

平时经常会遇到这种情况,比如修改一个单子,需要记录修改记录,这就需要做前后对比,所以自己定义了一个工具类,细节还可以优化,希望大家提出宝贵的意见。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnjiDescription {/*** 加上注解默认对比* @return*/String value();
}
public class ComparisonResult {private String key;private String label;private String previous;private String later;public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getLabel() {return label;}public void setLabel(String label) {this.label = label;}public String getPrevious() {return previous;}public void setPrevious(String previous) {this.previous = previous;}public String getLater() {return later;}public void setLater(String later) {this.later = later;}
}

想要学习资料的加我

public class CompareUtils {private final static String DATE_FORMATTR_SECOND = "yyyy-MM-dd HH:mm:ss";/*** 比较两个实体属性值,返回一有差异的属性* @param obj1      进行属性比较的对象1* @param obj2      进行属性比较的对象2* @return*/public static List<ComparisonResult> compareFields(Object obj1, Object obj2, Class clazz) throws Exception {try {List<String> ignoreList = getCompareFields(clazz);Map<String,String> descsMap = getFieldSwaggerValue(clazz);List<ComparisonResult> list = new ArrayList<>();// 只有两个对象都是同一类型的才有可比性if (obj1.getClass() == obj2.getClass()) {Class claz = obj1.getClass();// 获取object的属性描述PropertyDescriptor[] pds = Introspector.getBeanInfo(claz,Object.class).getPropertyDescriptors();for (PropertyDescriptor pd : pds) {String name = pd.getName();String label = descsMap.get(name);if (ignoreList != null && !ignoreList.contains(name)) {continue;}Method readMethod = pd.getReadMethod();Object o1 = readMethod.invoke(obj1);Object o2 = readMethod.invoke(obj2);String r1 = null,r2 = null;if (Objects.isNull(o1) && Objects.isNull(o2)){continue;}if (null == o1 || null == o2){setResult(o1, o2, name, label, list);continue;}if (compareField(o1, o2)) {setResult(o1, o2, name, label, list);}}}else{throw new Exception("对象类型不一致");}return list;} catch (Exception e) {throw new Exception("对象比较失败", e);}}/*** 获取比较的类中字段** @param objectClass* @return*/private static List<String> getCompareFields(Class objectClass) {Field[] fields = objectClass.getDeclaredFields();List<String> map = new ArrayList<>();for (Field f : fields) {boolean annotationPresent2 = f.isAnnotationPresent(AnjiDescription.class);if (annotationPresent2) {map.add(f.getName());}}return map;}/*** 获取实体类字段的description** @param clazz* @return*/private static Map<String, String> getFieldSwaggerValue(Class clazz) {Field[] fields = clazz.getDeclaredFields();Map<String, String> map = new HashMap<>();for (Field f : fields) {boolean annotationPresent2 = f.isAnnotationPresent(AnjiDescription.class);if (annotationPresent2) {AnjiDescription name = f.getAnnotation(AnjiDescription.class);String nameStr = name.value();map.put(f.getName(), nameStr);}}return map;}private static void setResult(Object o1, Object o2,String name,String label, List<ComparisonResult> list){Object ot = null;String r1 = null,r2 = null;if (!Objects.isNull(o1)){ot = o1;}else if(!Objects.isNull(o2)){ot = o2;}if (ot instanceof String){r1 = objectToString(o1);r2 = objectToString(o2);}else if(ot instanceof BigDecimal){System.out.println("BigDecimal");r1 = objectToString(o1);r2 = objectToString(o2);}else if (ot instanceof Integer){System.out.println("Integer");r1 = objectToString(o1);r2 = objectToString(o2);}else if (ot instanceof Boolean){System.out.println("Boolean");r1 = booleanToString(o1);r2 = booleanToString(o2);}else if (ot instanceof Long){System.out.println("Long");r1 = objectToString(o1);r2 = objectToString(o2);}else if (ot instanceof LocalDateTime){System.out.println("LocalDateTime");r1 = localDateTimeToString(o1);r2 = localDateTimeToString(o2);}ComparisonResult result = new ComparisonResult();result.setKey(name);result.setPrevious(r1);result.setLater(r2);result.setLabel(label);list.add(result);}private static boolean compareField(Object o1, Object o2){Boolean sign = false;Object ot = null;if (!Objects.isNull(o1)){ot = o1;}else if(!Objects.isNull(o2)){ot = o2;}if (ot instanceof String){sign = !o1.equals(o2);}else if(ot instanceof BigDecimal){System.out.println("BigDecimal");sign = ((BigDecimal) o1).compareTo((BigDecimal) o2) != 0 ? true : false;}else if (ot instanceof Integer){System.out.println("Integer");sign = ((Integer) o1).compareTo((Integer) o2) != 0 ? true : false;}else if (ot instanceof Boolean){System.out.println("Boolean");sign = ((Boolean) o1).compareTo((Boolean) o2) != 0 ? true : false;}else if (ot instanceof Long){System.out.println("Long");sign = ((Long) o1).compareTo((Long) o2) != 0 ? true : false;}else if (ot instanceof LocalDateTime){System.out.println("LocalDateTime");sign = ((LocalDateTime) o1).compareTo((LocalDateTime) o2) != 0 ? true : false;}return sign;}private static String objectToString(Object obj){if(null == obj){return "";}else {return obj.toString();}}private static String booleanToString(Object obj){if(null == obj){return null;}else {return(Boolean) obj ? "是" : "否";}}private static String localDateTimeToString(Object obj){if(null == obj){return null;}else {DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMATTR_SECOND);LocalDateTime ld = LocalDateTime.now();return df.format(ld);}}
}

测试

private String id;@AnjiDescription("标题")private String title;@AnjiDescription("作者")private String author;@AnjiDescription("时间long")private long postDate;@AnjiDescription("年龄")private int age;@AnjiDescription("金额")private BigDecimal price;@AnjiDescription("是否婚配")private Boolean sex;@AnjiDescription("时间戳")private LocalDateTime dateTime;long a ;Book book = new Book("1","java","fu",123,2,null,null, LocalDateTime.now(),1);book.setId("1");book.setTitle("java");book.setAuthor("fu");book.setPostDate(123);Book book1 = new Book("2","python","fu",0,3,new BigDecimal(BigInteger.ZERO),null,LocalDateTime.now()    ,1);book1.setId("2");book1.setTitle("python");book1.setAuthor("fu");book1.setPostDate(0);CompareUtils.compareFields(book,book1,book.getClass());

想要学习资料的加我

(类比较器)java对比两个相同实体类中属性的值的差异相关推荐

  1. Java对比两张Excel表的数据,java对比两个excel或者一张excel和数据库的一张表的数据是否相同,两张excel表格匹配相同的数据库...

    excel自动从数据库匹配相应的数据 vlookup函数:vlookup(lookup_value,table_array,col_index_num,[range_lookup]) 第一个:look ...

  2. java实现ListObject转List实体类,java实现Object转对象,java实现Object转实体类

    摘要:在java开发中,我们常常会遇到Object转对象的情况,最近我就遇到了这个问题,现在记录一下,方便日后自己查看复习! 一:查询Object类型的集合对象的方法如下: List topicLis ...

  3. java实体类没有映射文件_MyBatis自动生成实体类、DAO和XML映射文件,并去掉实体类中的getter和setter方法...

    今天花了3个多小时搞定了这个事情,写个Blog记录一下,先看一下最终生成的实体类吧. packagecom.mybatis.pojo;importlombok.AllArgsConstructor;i ...

  4. java实体类生成mysql表_springboot+mybatis通过实体类自动生成数据库表的方法

    前言 本章介绍使用mybatis结合mysql数据库自动根据实体类生成相关的数据库表. 首先引入相关的pom包我这里使用的是springboot2.1.8.RELEASE的版本 org.mybatis ...

  5. Java使用swagger时显示实体类注解问题

    第一步,在实体类中@ApiModel(description= "表名描述") 第二步,在字段属性中@ApiModelProperty(value = "字段备注&quo ...

  6. Java对比两张Excel表的数据_比较两个Excel表格并提取重复数据

    目标: 搜索并比较两个字段E列(表2)到E列(表1)将表2中的重复值返回到表3 显示和突出显示工作表1和2上的重复值突出显示 从工作表2复制重复条目,然后添加到工作表3 如果E列(表2)= E列(表1 ...

  7. java servlet类_[Java教程]与Servlet相关的类

    [Java教程]与Servlet相关的类 0 2017-08-31 17:00:15 有4个有关的类,通过servlet可以获得其中的三个,然后通过ServletConfig间接获取ServletCo ...

  8. abstract类_012 JAVA 抽象类、接口、String类的基础了解

    1.抽象方法和抽象类 抽象方法:使用abstract修饰的方法,没有方法体,只有声明.抽象方法可以当做是一种规范,让子类必须实现. 注意: 1.抽象方法没有方法体,只能以分号结尾 2.抽象方法只能声明 ...

  9. IDEA中根据数据库自动生成实体类,并自定义所生成的实体类中的注解 @Table @Id @...

    使用IDEA项目添加Hibernate扩展,生成实体类并配置实体类中的注解 一.使用Hibernate自动生成实体类 1.在项目上右键,选择Add Framework Support找到 Hibern ...

  10. JPA学习笔记---JPA实体Bean的建立---链接上一个博文:对实体Bean中属性进行操作:保存日期类型,设置字段的长度,名字,是否为空,可以声明枚举字段;可以存放二进制数据,可以存放

    3.给上述生成的那个name字段:更改数据库中的字段名,是否为空,字段长度的设定,只需要   在Person.java文件中,加上 @Column(length=10,nullable=false,n ...

最新文章

  1. javascript tab切换类LixTabs最新版
  2. crypto安装_CryptoPP库在Linux系统下的安装与测试
  3. 百度前端技术学院html任务,重回百度前端技术学院第一天 HTML复习
  4. Docker镜像分层和临时容器
  5. 二十年后的回眸(4)——离奇的邂逅
  6. linux c之通过管道父子进程实现同步通信
  7. android 添加随意拖动的桌面悬浮窗口,android 添加随意拖动的桌面悬浮窗口
  8. 计算机关于word试题及答案,职称计算机考试Word操作试题及答案
  9. sftp api java_使用JSch实现SFTP文件传输
  10. java构建大根堆_构建大根堆
  11. C#用域账号登陆,访问网络路径
  12. Windows与Linux下查看占用端口的进程
  13. 170705、springboot编程之自定义properties
  14. [电影]《指环王》新老三部曲完全赏析(双塔)
  15. 笔记本电脑如何安装Linux系统
  16. Python学习20230111
  17. 对自己狠一点-----胡言乱语
  18. 【工具】MobaXterm常用设置
  19. 【渝粤题库】陕西师范大学202501 法语(二)作业
  20. L1-011~L1-015

热门文章

  1. HTTP1.0、HTTP2.0、HTTP 3.0及HTTPS简要介绍
  2. 蓝桥杯 基础练习 圆的面积
  3. excel中的菜单栏自定义_如何在Excel中自定义和使用状态栏
  4. 微生物组-扩增子16S分析和可视化(2022.10)
  5. softice使用(1)- 在VMware Workstation 中使用SoftICE zz xfocus
  6. LINUX下运行.sh文件出现Syntax error: end of file unexpected (expecting “then”)最方便解决方法
  7. 转:淘宝客搜索链接技巧首度分享
  8. 淘宝客淘宝联盟解析二合一链接获取优惠链接还原二合一,提取优惠信息
  9. mysql语句中单引号、双引号、反引号用法与区别
  10. MATLAB高维矩阵的求和、索引