当前位置:   article > 正文

json对比工具类_复杂json对比 工具类

复杂json对比 工具类

记录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拼接父类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.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"));
	}
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/788174
推荐阅读
相关标签
  

闽ICP备14008679号