skip to Main Content

I have 2 JSON objects
First

    {
  "fields": [
    {
      "name": "address",
      "type": "string",
      "default": "NONE"
    },
    {
      "name": "age",
      "type": "int",
      "default": "NONE"
    }
  ]
}

and second JSON

{
  "fields": [
    {
      "name": "age",
      "type": "int",
      "default": "NONE"
    },
    {
      "name": "address",
      "type": "string",
      "default": "NONE"
    }
  ]
}

Please note that

  1. fields object may not be always named "name","type" and "default"
  2. the field values may not be always primitives. For example an
    address which is of type "ArrayList".

How do I compare the JSON objects in such cases since these are equivalent JSON objects except for field value ordering. I am using Java 11 for my work. I tried using a custom Field class and map individual fields element to the class and then sort it but then the solution is not generic.

Following is one solution I am trying

public class JsonComparator {
    public static boolean compareJson(String json1, String json2) {
        JSONObject obj1 = new JSONObject(json1);
        JSONObject obj2 = new JSONObject(json2);

        JSONArray fields1 = obj1.getJSONArray("fields");
        JSONArray fields2 = obj2.getJSONArray("fields");
    
        fields1 = sortJsonArray(fields1);
        fields2 = sortJsonArray(fields2);

        for (int i = 0; i < fields1.length(); i++) {
            JSONObject field1 = fields1.getJSONObject(i);
            JSONObject field2 = fields2.getJSONObject(i);

            for (String key : field1.keySet()) {
                if (!field1.get(key).equals(field2.get(key))) {
                    return false;
                }
            }
        }

        return true;
    }

    private static JSONArray sortJsonArray(JSONArray array) {
        ArrayList<JSONObject> sortedList = new ArrayList<>();
        for (int i = 0; i < array.length(); i++) {
            sortedList.add(array.getJSONObject(i));
        }
        sortedList.sort(new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                return o1.toString().compareTo(o2.toString());
            }
        });
        return new JSONArray(sortedList);
    }
}

but need to analyze the JSON objects since all the JSON object need not contain the field "fields" and one JSON can be superset of other so trying to see if a better library available to give a solution.

2

Answers


  1. You could try JSONCompare from JSONAssert library

    <dependency>
        <groupId>org.skyscreamer</groupId>
        <artifactId>jsonassert</artifactId>
        <version>1.5.0</version>
    </dependency>
    

    with compareMode as STRICT,LENIENT,IGNORE_ORDER etc.

     public static boolean isTwoJsonEquals(JSONObject firstObj,JSONObject secondObj, JSONCompareMode compareMode){
        try {
          JSONCompareResult result = JSONCompare.compareJSON(firstObj, secondObj, compareMode);
    
          return result.passed();
        } catch (JSONException e) {
          e.printStackTrace();
        }
        return false;
      }
    
    Login or Signup to reply.
  2. You may try library Josson & Jossons. It has JSON join, set and compare operation.

    https://github.com/octomix/josson

    Deserialization

    Jossons jossons = new Jossons();
    jossons.putDataset("json1", Josson.fromJsonString(
        "{" +
        "  "fields": [" +
        "    {" +
        "      "name": "address"," +
        "      "type": "string"," +
        "      "default": "NONE"" +
        "    }," +
        "    {" +
        "      "name": "age"," +
        "      "type": "int"," +
        "      "default": "NONE"" +
        "    }" +
        "  ]" +
        "}"));
    jossons.putDataset("json2", Josson.fromJsonString(
        "{" +
        "  "fields": [" +
        "    {" +
        "      "name": "age"," +
        "      "type": "int"," +
        "      "default": "NONE"" +
        "    }," +
        "    {" +
        "      "name": "gender"," +
        "      "type": "string"," +
        "      "default": "NONE"" +
        "    }" +
        "  ]" +
        "}"));
    

    Subtract right from left

    JsonNode node = jossons.evaluateQuery("json1->fields <-< json2->fields");
    System.out.println(node.toPrettyString());
    // Output:
    // [ {
    //   "name" : "address",
    //   "type" : "string",
    //   "default" : "NONE"
    // } ]
    

    Subtract left from right

    JsonNode node = jossons.evaluateQuery("json1->fields >-> json2->fields");
    System.out.println(node.toPrettyString());
    // Output:
    // [ {
    //   "name" : "gender",
    //   "type" : "string",
    //   "default" : "NONE"
    // } ]
    

    Symmetric difference

    JsonNode node = jossons.evaluateQuery("json1->fields <-> json2->fields");
    System.out.println(node.toPrettyString());
    // Output:
    // [ {
    //   "name" : "address",
    //   "type" : "string",
    //   "default" : "NONE"
    // }, {
    //   "name" : "gender",
    //   "type" : "string",
    //   "default" : "NONE"
    // } ]
    

    Equals

    JsonNode node = jossons.evaluateQuery("json1->fields <==> json2->fields");
    System.out.println(node.toPrettyString());
    // Output:
    // false
    

    Not equals

    JsonNode node = jossons.evaluateQuery("json1->fields <!=> json2->fields");
    System.out.println(node.toPrettyString());
    // Output:
    // true
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search