java实现两个json的深度对比

时间:2024-01-25 22:10:55

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);