java实现两个json的深度对比
两个json的深度对比
在网上找了好多资料都没有找到想要的,还是自己写个吧!
上代码!!!
1.pom.xml中加入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
2.新建CompareJson.java类
package com.suncompass.huanjinyingji.uitl; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature; import java.util.*; public class CompareJson { private static final String SysRoot = "sys_root";
private static final String SysType = "sys_type";
private static final String SysObj = "sys_obj";
private static final String SysNew = "sys_new";
private static final String SysOld = "sys_old";
private static final String TypeNew = "new";
private static final String TypeDelete = "delete";
private static final String TypeDifference = "difference"; private String itemKey;
private List<String> ignoreKeys = new ArrayList<>(); public CompareJson(String itemKey) {
this.itemKey = itemKey;
} public CompareJson(String itemKey, String ignoreKeys) {
this.itemKey = itemKey;
this.ignoreKeys = Arrays.asList(ignoreKeys.split("\\,"));
} public static void main(String[] args) {
final String json1 = "{\"id\":\"1\",\"name\":\"n1\",\"height\":null,\"list\":[1,2,3],\"age\":0,\"items\":[{\"id\":\"11\",\"name\":\"n11\",\"copyId\":\"1\"},{\"id\":\"12\",\"name\":\"n12\",\"copyId\":\"2\"}]}";
final String json2 = "{\"id\":\"1\",\"name\":\"n2\",\"height\":180,\"list\":[3,4,5],\"age\":null,\"items\":[{\"id\":\"11\",\"name\":\"n11\",\"copyId\":\"3\"},{\"id\":\"12\",\"name\":\"n13\",\"copyId\":\"2\"}]}";
String resultStr = new CompareJson("copyId").compareJson(json1, json2);
System.out.println(resultStr);
} private void compareJson(JSONObject jsonObject1, JSONObject jsonObject2, Map<String, Object> objectMap) {
Iterator<String> iterator = jsonObject1.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (ignoreKeys.contains(key)) {
continue;
} Object value1 = jsonObject1.get(key);
Object value2 = jsonObject2.get(key);
compareJson(key, value1, value2, objectMap);
}
} private void compareJson(JSONArray jsonArray1, JSONArray jsonArray2, List<Map<String, Object>> arrayMap) { JSONArray jsonArray = (JSONArray) jsonArray1.clone();
if (jsonArray2 != null) {
jsonArray.addAll(jsonArray2);
} for (int i = 0; i < jsonArray.size(); i++) { JSONObject jsonObject = (JSONObject) jsonArray.get(i);
Object keyValue = jsonObject.get(this.itemKey);
if (keyValue == null) {
continue;
} JSONObject jsonObject1 = null;
for (int j = 0; j < jsonArray1.size(); j++) {
JSONObject jsonObj = (JSONObject) jsonArray1.get(j);
if (keyValue.equals(jsonObj.get(this.itemKey))) {
jsonObject1 = jsonObj;
break;
}
} JSONObject jsonObject2 = null;
for (int j = 0; j < jsonArray2.size(); j++) {
JSONObject jsonObj = (JSONObject) jsonArray2.get(j);
if (keyValue.equals(jsonObj.get(this.itemKey))) {
jsonObject2 = jsonObj;
break;
}
} Map<String, Object> objectMap = new HashMap<>();
if (jsonObject1 != null && jsonObject2 == null) {
objectMap.put(this.itemKey, keyValue);
objectMap.put(SysType, TypeNew);
objectMap.put(SysObj, jsonObject1);
} else if (jsonObject1 == null && jsonObject2 != null) {
objectMap.put(this.itemKey, keyValue);
objectMap.put(SysType, TypeDelete);
objectMap.put(SysObj, jsonObject2);
} else {
Map<String, Object> differenceMap = new HashMap<>();
compareJson(jsonObject1, jsonObject2, differenceMap);
if (differenceMap.size() > 0) {
objectMap.put(this.itemKey, keyValue);
objectMap.put(SysType, TypeDifference);
objectMap.put(SysObj, differenceMap);
}
} if (objectMap.size() > 0) { Map<String, Object> findMap = null;
for (Map<String, Object> map : arrayMap) {
if (keyValue.equals(map.get(this.itemKey))) {
findMap = map;
break;
}
} if (findMap == null) {
arrayMap.add(objectMap);
}
}
}
} private void compareJson(String key, Object json1, Object json2, Map<String, Object> resultMap) {
if (json1 instanceof JSONObject) { Map<String, Object> objectMap = new HashMap<>();
compareJson((JSONObject) json1, (JSONObject) json2, objectMap);
if (objectMap.size() > 0) {
resultMap.put(key, objectMap);
} } else if (json1 instanceof JSONArray) { JSONArray jsonArray = (JSONArray) json1;
if (jsonArray != null && jsonArray.size() > 0) {
if (!(jsonArray.get(0) instanceof JSONObject)) { //["1","2"],[1,2]...
Map<String, Object> compareMap = new HashMap<>();
compareMap.put(SysNew, json1);
compareMap.put(SysOld, json2);
resultMap.put(key, compareMap);
return;
}
} List<Map<String, Object>> arrayMap = new ArrayList<>();
compareJson((JSONArray) json1, (JSONArray) json2, arrayMap);
if (arrayMap.size() > 0) {
resultMap.put(key, arrayMap);
} } else if ((json1 == null && json2 != null) || (json1 != null && !json1.equals(json2))) {
Map<String, Object> compareMap = new HashMap<>();
compareMap.put(SysNew, json1);
compareMap.put(SysOld, json2);
resultMap.put(key, compareMap);
}
} public String compareJson(String json1, String json2) {
Object jsonObj1 = JSONObject.parse(json1);
Object jsonObj2 = JSONObject.parse(json2);
Map<String, Object> resultMap = new HashMap<>();
compareJson(SysRoot, jsonObj1, jsonObj2, resultMap);
String resultStr = JSON.toJSONString(resultMap.get(SysRoot), new SerializerFeature[]{SerializerFeature.WriteMapNullValue});
return resultStr;
}
}
3.运行main函数输出
{
"name": {
"sys_new": "n1",
"sys_old": "n2"
},
"list": {
"sys_new": [1, 2, 3],
"sys_old": [3, 4, 5]
},
"items": [{
"copyId": "1",
"sys_type": "new",
"sys_obj": {
"copyId": "1",
"name": "n11",
"id": "11"
}
}, {
"copyId": "2",
"sys_type": "difference",
"sys_obj": {
"name": {
"sys_new": "n12",
"sys_old": "n13"
}
}
}, {
"copyId": "3",
"sys_type": "delete",
"sys_obj": {
"copyId": "3",
"name": "n11",
"id": "11"
}
}],
"age": {
"sys_new": 0,
"sys_old": null
},
"height": {
"sys_new": null,
"sys_old": 180
}
}
总结:
1.支持深度;
2.支持集合指定标识设置(itemKey);
3.支持数组(如:[1,2,3]);
4.去除重复;
5.支持排除键设置(ignoreKeys);
java实现两个json的深度对比的更多相关文章
- 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)
本篇文章主要介绍了"两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)",主要涉及到两款JSON类库Jackson与JSON-lib的性能对比(新增第三款 ...
- Java中的ReentrantLock和synchronized两种锁定机制的对比
问题:多个访问线程将需要写入到文件中的数据先保存到一个队列里面,然后由专门的 写出线程负责从队列中取出数据并写入到文件中. http://blog.csdn.net/top_code/article/ ...
- 比较任意两个JSON串是否相等(比较对象是否相等)JAVA版
废话少说,直接入题. 在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是Map.List互相嵌套成的复杂数据结构. 比较对象是否相等,常见的思路 ...
- Java构造和解析Json数据的两种方法详解二
在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Jso ...
- Java中两个List对比的算法
Java中两个List对比的算法: // 测试数据 // tdcsDdt.add("Z"); // tdcsDdt.add("B"); // tdcsDdt ...
- Java构造和解析Json数据的两种方法详解二——org.json
转自:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/24/3096437.html 在www.json.org上公布了很多JAVA下的jso ...
- Java构造和解析Json数据的两种方法详解一——json-lib
转自:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/23/3096001.html 在www.json.org上公布了很多JAVA下的jso ...
- Java中两种实现多线程方式的对比分析
本文转载自:http://www.linuxidc.com/Linux/2013-12/93690.htm#0-tsina-1-14812-397232819ff9a47a7b7e80a40613cf ...
- Splunk和ELK深度对比
转自:http://blog.51cto.com/splunkchina/1948105 日志处理两大生态Splunk和ELK深度对比 heijunmasd 0人评论 5312人阅读 2017-07- ...
随机推荐
- jenkins中使用变量
查看jenkins内置变量: 1.新建一个job: 2.构建-增加构建步骤-执行shell: 3.点击 可用的环境变量列表 即可查看 如WORKSPACE : 作为工作空间分配给构建目录的绝对路径 ...
- VAD树结构体的属性以及遍历
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html VAD树的属性以及遍历 前面学习过的PFNDATABSAE是管理物 ...
- 03 Node.js学习笔记之根据http请求路径返回不同数据
在Nodejs中,当客户端请求的路径不同时,NodeJS处理返回不同的数据 步骤: //1.载入http模块 var http=require('http'); //2.创建一个http服务 var ...
- java架构之路-(Redis专题)简单聊聊redis分布式锁
这次我们来简单说说分布式锁,我记得过去我也过一篇JMM的内存一致性算法,就是说拿到锁的可以继续操作,没拿到的自旋等待. 思路与场景 我们在Zookeeper中提到过分布式锁,这里我们先用redis实现 ...
- 从Go语言编码角度解释实现简易区块链——实现交易
在公链基础上实现区块链交易 区块链的目的,是能够安全可靠的存储交易,比如我们常见的比特币的交易,这里我们会以比特币为例实现区块链上的通用交易.上一节用简单的数据结构完成了区块链的公链,本节在此基础上对 ...
- Java学习笔记十二--集合(三)
第一节课 返回值 方法名 作用 void add(index,elemnet) 在指定的索引处添加元素 object get(index) 返回指定索引处的元素 int indexOf(object) ...
- Visual Studio Code 添加C/C++编译功能
VS Code作为一个文本/代码编辑器,相较于VS比较轻量化,而且可以支持C/C++.Python等多种语言,并具有丰富的拓展模块. 但是作为一个编辑器,在VS Code上安装C/C++模块之后,并不 ...
- 数据结构(四十六)插入排序(1.直接插入排序(O(n²)) 2.希尔排序(O(n3/2)))
一.插入排序的基本思想 从初始有序的子集合开始,不断地把新的数据元素插入到已排列有序子集合的合适位置上,使子集合中数据元素的个数不断增多,当子集合等于集合时,插入排序算法结束.常用的 插入排序算法有直 ...
- (四)适配器Adapter
只对简单应用进行描述.适配器与ListView配合使用可以快速生成item,效果如下例所示 一.简单模式 方式一 xml <ListView android:id="@+id/lv_t ...
- C# leetcode 之 096 不同的二叉搜索树
C# leetcode 之 096 不同的二叉搜索树 题目描述 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 二叉搜索树定义 左子树上所有节点的值小于根节点, 右子树上左右 ...