一款对象差异比较工具方法

需求

1.为了记录一张表的操作日志,就是记录管理员进行了什么操作,需要记录下这个操作,并且要记录修改前 和 修改后的信息。

实现

1.下面是一段java 代码的实现。

package com.xescm.epc.utils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 比较同一类 的 两个实列 哪些属性存在差异
 * 用于数据更新前后 对比。
 *
 * @author huxingnan
 * @date 2018/3/29 18:55
 */
public class FieldComparetor {


    public static List compareFields(Object oldObj, Object newObj, String... ignoreFieldNames) {
        try {
            List ignoreFieldNameList = Lists.newArrayList();
            if (ignoreFieldNames != null) {
                ignoreFieldNameList = Arrays.asList(ignoreFieldNames);
            }
            List compareResults = Lists.newArrayList();

            Class clazz;

            if(oldObj.getClass() == Object.class || newObj.getClass() ==Object.class){
                //如果是 Object 类型 不必对
                return compareResults;
            }
            if (oldObj.getClass() == newObj.getClass()) {
                // 属于同一种 类型
                clazz = oldObj.getClass();
            } else if (oldObj.getClass().isAssignableFrom(newObj.getClass())) {
                //newObj  是 oldObj 的子类
                clazz = oldObj.getClass();
            } else if (newObj.getClass().isAssignableFrom(oldObj.getClass())) {
                //oldObj 是 newObj 的子类
                clazz = newObj.getClass();
            } else {
                //没必要对比了
                return compareResults;
            }


            // 获取object的属性描述
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                    Object.class).getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
                String name = pd.getName();// 属性名
//
                if (ignoreFieldNameList.contains(name)) {
                    continue;
                }
                Method readMethod = pd.getReadMethod();// get方法
                // 在oldObj上调用get方法等同于获得oldObj的属性值
                Object oldValue = readMethod.invoke(oldObj);
                // 在newObj调用get方法等同于获得newObj的属性值
                Object newValue = readMethod.invoke(newObj);

                if (oldValue == null && newValue == null) {
                    continue;
                }
                if (oldValue == null) {
                    compareResults.add(new CompareResult(null, newValue.toString(), name));
                    continue;
                }
                if (newValue == null) {
                    compareResults.add(new CompareResult(oldValue.toString(), null, name));
                    continue;
                }
                if (!oldValue.equals(newValue)) {// 比较这两个值是否相等,不等就可以放入list了
                    compareResults.add(new CompareResult(oldValue.toString(), newValue.toString(), name));
                }
            }
            return compareResults;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * descripion: 校验两对象差异
     * author: zhixing.wang
     * date: 2018/3/30 11:21
     * param: [requestBean, fitBean]
     * return: java.lang.String
     */
    public static String compareBean(Object requestBean, Object fitBean) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            // 请求对象的Field
            Class requestClazz = requestBean.getClass();
            Field[] requestFields = requestClazz.getDeclaredFields();
            // 本地对象的Field
            Class fitClazz = fitBean.getClass();
            Field[] fitFields = fitClazz.getDeclaredFields();

            Map map = Maps.newHashMap();
            for (Field field : fitFields) {
                map.put(field.getName(), field.getName());
            }
            // serialVersionUID 不做比较
            for (Field field : requestFields) {
                if ("serialVersionUID".equals(field.getName())) {
                    continue;
                }
                // 请求对象有Field 但 本地对象没有的Field 不做比较
                if (!map.containsKey(field.getName())) {
                    continue;
                }
                PropertyDescriptor requestPd = new PropertyDescriptor(field.getName(), requestClazz);
                PropertyDescriptor fitPd = new PropertyDescriptor(field.getName(), fitClazz);
                // 获取Field的get方法
                Method getRequestMethod = requestPd.getReadMethod();
                Method getFitMethod = fitPd.getReadMethod();
                // 获取Field属性值
                Object requestField = getRequestMethod.invoke(requestBean);
                Object fitField = getFitMethod.invoke(fitBean);
                // 返回异常信息
                if (!Objects.equals(requestField, fitField)) {
                    stringBuilder.append(field.getName()).append("不正确;");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    /**
     * 比较结果
     */
    @Data
    @AllArgsConstructor
    public static class CompareResult {
        private String oldValue;
        private String newValue;
        private String fieldName;
    }
}


你可能感兴趣的:(一款对象差异比较工具方法)