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

(类比较器)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());

想要学习资料的加我

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值