java实现对象对比工具类

说明

此工具类对比两个Java对象相同属性以及不同属性

对比示例/结果

对比示例,可以对比实体,实体中嵌套实体,实体中嵌套集合等

{
	"id":"",
	"username":"",
	"age":0,
	"address":[
		{
			"province":"",
			"city":"",
			"disrtict":""
		}
	],
	"details":{
		"sex":"",
		"mobile":""
	}
}

一下对比结果(更多测试可使用下方源码进行测试):

全部对比:
相同列==>[id, age, address_city, address_id, details_sex]
不同列==>[username, address_province, address_disrtict, details_mobile]

默认过滤策略(id存在于默认策略,所以被过滤掉了):
相同列==>[age, address_city, details_sex]
不同列==>[username, address_province, address_disrtict, details_mobile]

指定列对比(只对比username、province):
相同列==>[]
不同列==>[username, address_province]

指定列不对比(不对比username、province):
相同列==>[id, age, address_city, address_id, details_sex]
不同列==>[address_disrtict, details_mobile]

指定列不对比+默认过滤策略(不对比username、province+默认过滤策略):
相同列==>[age, address_city, details_sex]
不同列==>[address_disrtict, details_mobile]

指定列不对比+默认过滤策略(不对比username、address+默认过滤策略):
相同列==>[age, details_sex]
不同列==>[details_mobile]

源码

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 对象对比工具类
 * @author: guo-coffee
 */
public class ComparedUtils {

    /**
     * 示例说明(更多事例可查看main方法):
     * 对比json:{"id":"tom","username":"tom","age":18,"address":[{"province":"上海市"},{"city":"上海市"},{"disrtict":"静安区"},{"id":"静安区"}]}
     *
     * 示例一:调用compareJson(JSONObject json1, JSONObject json2, List<String> compareList)
     *      假设指定username、address_province两列对比,compareList中需要放入username、address、address_province。
     *      解释:若compareList集合中不放address,则表示整个address均不会进入比较,所以json嵌套多层时,将父key也需要放入compareList中
     *
     * 事例二:调用compareJson(JSONObject json1, JSONObject json2, List<String> filterList,boolean flag)
     *      1、假设指定username、address_province两列不进行对比,filterList中需要放入username、address_province即可
     *      2、假设整个address均不进行比对,filterList中需要放入username、address即可
     */

    /**
     * 默认过滤列名(由于项目会继承一些基类[例如ID、操作人、操作时间、修改人、修改时间等],基类中属性对比无任何意义,可以过滤掉)
     */
    private static final List<String> DEFAULT_FILTER_COLUMNS = Arrays.asList("id","createDate","updateDate","createPersonId","createPersonName","updatePersonId","updatePersonName","concurrencyVersion","delflag","tendId");

    /**
     * json嵌套多层时,父子key拼接字符
     */
    private static final String SEPARATOR = "_";

    /**
     * 两个对象对比(全部列对比)
     * @param json1 对比对象,必传
     * @param json2 对比对象,必传
     * @return
     */
    public static Map<String,List<String>> compareJson(JSONObject json1, JSONObject json2){
        return compareJson(json1,json2,false);
    }

    /**
     * 两个对象对比
     * @param json1 对比对象,必传
     * @param json2 对比对象,必传
     * @param flag 是否采用默认过滤策略-->true:采用 false:不采用
     * @return
     */
    public static Map<String,List<String>> compareJson(JSONObject json1, JSONObject json2, boolean flag){
        return compareJson(json1,json2,null,null,flag,null,null,new ArrayList<>(),new ArrayList<>());
    }

    /**
     * 两个对象对比
     * @param json1 对比对象,必传
     * @param json2 对比对象,必传
     * @param compareList 要比较的列
     * @return
     */
    public static Map<String,List<String>> compareJson(JSONObject json1, JSONObject json2, List<String> compareList){
        return compareJson(json1,json2,compareList,null,false,null,null,new ArrayList<>(),new ArrayList<>());
    }

    /**
     * 两个对象对比
     * @param json1 对比对象,必传
     * @param json2 对比对象,必传
     * @param filterList 不需要比较的列
     * @param flag 是否需要过滤默认列-->true:需要 false:不需要
     * @return
     */
    public static Map<String,List<String>> compareJson(JSONObject json1, JSONObject json2, List<String> filterList,boolean flag){
        return compareJson(json1,json2,null,filterList,flag,null,null,new ArrayList<>(),new ArrayList<>());
    }

    /**
     * 父类递归
     * @param json1 对比对象
     * @param json2 对比对象
     * @param compareList 要比较的列
     * @param filterList 不需要比较的列
     * @param flag 是否需要过滤默认列-->true:需要 false:不需要
     * @param key 当前比较的key,默认传null,主要用于递归时使用
     * @param parentKey 拼接父类key,避免json嵌套多层时,返回key一致问题,默认传null,主要用于递归时使用
     * @param equalsList 相同列,默认传new ArrayList<String>(),主要用于递归使用
     * @param diffList 不同列,默认传传new ArrayList<String>(),主要用于递归使用
     * @return
     */
    private static Map<String,List<String>> compareJson(JSONObject json1, JSONObject json2,List<String> compareList,List<String> filterList,boolean flag, String key,String parentKey,List<String> equalsList,List<String> diffList) {
        Map<String,List<String>> map = new HashMap<>(2);
        Iterator i = json1.keySet().iterator();
        while (i.hasNext()) {
            // 当前比较的列
            key = (String) i.next();
            // 嵌套JSONArray时,当前key拼接父类key
            String str = StringUtils.isBlank(parentKey) ? key : parentKey + SEPARATOR + key;
            if (
                // 比较全部
                    ((compareList == null || compareList.isEmpty()) && (filterList == null || filterList.isEmpty()) && !flag)
                            // 在【要比较的列】中
                            || (compareList != null && !compareList.isEmpty() && compareList.contains(str))
                            // 不默认过滤 并且 不在【不需要比较的列】中
                            || (filterList != null && !filterList.isEmpty() && !filterList.contains(str) && !flag)
                            // 过滤默认 并且 不在默认列 并且 不在【不需要比较的列】中
                            || (filterList != null && !filterList.isEmpty() && !filterList.contains(str) && flag && !DEFAULT_FILTER_COLUMNS.contains(key))
                            // 只过滤默认
                            || ((filterList == null || filterList.isEmpty()) && flag && !DEFAULT_FILTER_COLUMNS.contains(key))
            ) {
                /**
                 * 调用-->Object
                 */
                if (json1.get(key) != null && json2.get(key) != null){
                    compareJson(json1.get(key), json2.get(key), compareList, filterList, flag, key, parentKey, equalsList, diffList);
                } else if (json1.get(key) == null && json2.get(key) == null) {
                    equalsList.add(key);
                } else {
                    diffList.add(key);
                }
            }
        }
        // 嵌套JSONArray时,只要有一列不一致,均为不一致
        equalsList.removeAll(diffList);
        // 嵌套JSONArray时,存在列明重复情况,集合去重处理
        map.put("equalsList",equalsList.stream().distinct().collect(Collectors.toList()));
        map.put("diffList",diffList.stream().distinct().collect(Collectors.toList()));
        return map;
    }

    /**
     * Object
     */
    private static void compareJson(Object json1, Object json2,List<String> compareList,List<String> filterList,boolean flag, String key,String parentKey,List<String> equalsList,List<String> diffList) {
        if (json1 instanceof JSONObject) {
            // 拼接父类key,避免json嵌套多层时,返回key一致问题
            parentKey = StringUtils.isBlank(parentKey)?key:parentKey+SEPARATOR+key;
            /**
             * 调用-->父类递归
             */
            compareJson((JSONObject) json1, (JSONObject) json2, compareList,filterList, flag, key ,parentKey,equalsList,diffList);
        } else if (json1 instanceof JSONArray) {
            /**
             * 调用-->jsonArray
             */
            compareJson((JSONArray) json1, (JSONArray) json2, compareList, filterList, flag, key ,parentKey,equalsList,diffList);
        } else if (json1 instanceof String) {
            try {
                String json1ToStr = json1.toString();
                String json2ToStr = json2.toString();
                /**
                 * 调用-->json字符串
                 */
                compareJson(json1ToStr, json2ToStr, key , parentKey,equalsList,diffList);
            } catch (Exception e) {
                System.out.println("转换发生异常 key:" + key);
                e.printStackTrace();
            }
        } else {
            /**
             * 调用-->json字符串
             */
            compareJson(json1.toString(), json2.toString(), key , parentKey,equalsList,diffList);
        }
    }

    /**
     * json字符串
     */
    private static void compareJson(String str1, String str2, String key,String parentKey,List<String> equalsList,List<String> diffList) {
        // 拼接父类key,避免json嵌套多层时,返回key一致问题
        parentKey = StringUtils.isBlank(parentKey)?key:parentKey+SEPARATOR+key;
        if (!str1.equals(str2)) {
            // 不一致的key
            diffList.add(parentKey);
        } else {
            // 一致
            equalsList.add(parentKey);
        }
    }

    /**
     * jsonArray
     */
    private static void compareJson(JSONArray json1, JSONArray json2,List<String> compareList,List<String> filterList,boolean flag, String key, String parentKey,List<String> equalsList,List<String> diffList) {
        // 拼接父类key,避免json嵌套多层时,返回key一致问题
        if (json1 != null && json2 != null && json1.size() == json2.size()) {
            Iterator i1 = json1.iterator();
            Iterator i2 = json2.iterator();
            while (i1.hasNext()) {
                /**
                 * 调用-->Object
                 */
                compareJson(i1.next(), i2.next(),compareList,filterList, flag, key , parentKey , equalsList,diffList);
            }
        } else {
            // JSONArray只要有一个为null则会不一致
            diffList.add(parentKey);
        }
    }

    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        String st1 = "{\"id\":\"tom\",\"username\":\"tom\",\"age\":18,\"address\":[{\"province\":\"上海市\"},{\"city\":\"上海市\"},{\"disrtict\":\"静安区\"},{\"id\":\"静安区\"}],\"details\":{\"sex\":\"男\",\"mobile\":\"13811112222\"}}";
        String st2 = "{\"id\":\"tom\",\"username\":\"tom1\",\"age\":18,\"address\":[{\"province\":\"上海市1\"},{\"city\":\"上海市\"},{\"disrtict\":\"静安区1\"},{\"id\":\"静安区\"}],\"details\":{\"sex\":\"男\",\"mobile\":\"13811113333\"}}";

        JSONObject jsonObject1 = JSONObject.fromObject(st1);
        JSONObject jsonObject2 = JSONObject.fromObject(st2);

        System.out.println("全部对比:");
        Map<String,List<String>> map = compareJson(jsonObject1, jsonObject2);
        System.out.println("相同列==>"+map.get("equalsList"));
        System.out.println("不同列==>"+map.get("diffList"));

        System.out.println("默认过滤策略(id存在于默认策略,所以被过滤掉了):");
        Map<String,List<String>> map1 = compareJson(jsonObject1, jsonObject2,true);
        System.out.println("相同列==>"+map1.get("equalsList"));
        System.out.println("不同列==>"+map1.get("diffList"));

        System.out.println("指定列对比(只对比username、province):");
        // 注:要比较province,必须将address也放入集合中
        Map<String,List<String>> map2 = compareJson(jsonObject1, jsonObject2,Arrays.asList("username","address","address_province"));
        System.out.println("相同列==>"+map2.get("equalsList"));
        System.out.println("不同列==>"+map2.get("diffList"));

        System.out.println("指定列不对比(不对比username、province):");
        Map<String,List<String>> map3 = compareJson(jsonObject1, jsonObject2,Arrays.asList("username","address_province"),false);
        System.out.println("相同列==>"+map3.get("equalsList"));
        System.out.println("不同列==>"+map3.get("diffList"));

        System.out.println("指定列不对比+默认过滤策略(不对比username、province+默认过滤策略):");
        Map<String,List<String>> map4 = compareJson(jsonObject1, jsonObject2,Arrays.asList("username","address_province"),true);
        System.out.println("相同列==>"+map4.get("equalsList"));
        System.out.println("不同列==>"+map4.get("diffList"));

        System.out.println("指定列不对比+默认过滤策略(不对比username、address+默认过滤策略):");
        Map<String,List<String>> map5 = compareJson(jsonObject1, jsonObject2,Arrays.asList("username","address"),true);
        System.out.println("相同列==>"+map5.get("equalsList"));
        System.out.println("不同列==>"+map5.get("diffList"));
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值