记录json对比工具类
/*** @program: bedrock* @description: 复杂对象比较工具类* @author: * @create: 2022-01-26 22:49**/import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.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拼接父类keyString 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)) {// 不一致的keydiffList.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.parseObject(st1);JSONObject jsonObject2 = JSONObject.parseObject(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"));}
}