Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Overview

In this tutorial, we’ll have a look at comparing two JSON objects using Jackson — a JSON processing library for Java.

2. Maven Dependency

First, let’s add the jackson-databind Maven dependency:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

3. Using Jackson to Compare Two JSON Objects

We'll be using the ObjectMapper class to read an object as a JsonNode.

Let's create an ObjectMapper:

ObjectMapper mapper = new ObjectMapper();

3.1. Compare Two Simple JSON Objects

Let’s begin by using the JsonNode.equals method. The equals() method performs a full (deep) comparison.

Suppose we have a JSON string defined as the s1 variable:

{
    "employee":
    {
        "id": "1212",
        "fullName": "John Miles",
        "age": 34
    }
}

And we want to compare it with another JSON, s2:

{   
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles"
    }
}

Let's read the input JSON as JsonNode and compare:

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

It's important to note that even though the order of attributes in input JSON variables s1 and s2 is not the same, the equals() method ignores the order and treats them as equal.

3.2. Compare Two JSON Objects With a Nested Element

Next, we'll see how to compare two JSON objects having nested elements.

Let's begin with a JSON defined as the s1 variable:

{ 
    "employee":
    {
        "id": "1212",
        "fullName":"John Miles",
        "age": 34,
        "contact":
        {
            "email": "[email protected]",
            "phone": "9999999999"
        }
    }
}

As we can see, the JSON contains a nested element contact.

We want to compare it with another JSON defined by s2:

{
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles",
        "contact":
        {
            "email": "[email protected]",
            "phone": "9999999999"
        }
    }
}

Let's read the input JSON as JsonNode and compare:

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

Again, we should notice that equals() can also compare two input JSON objects with nested elements.

3.3. Compare Two JSON Objects Containing a List Element

Similarly, we can also compare two JSON objects that contain a list element.

Let's consider this JSON defined as s1:

{
    "employee":
    {
        "id": "1212",
        "fullName": "John Miles",
        "age": 34,
        "skills": ["Java", "C++", "Python"]
    }
}

We are comparing it with another JSON, s2:

{
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles",
        "skills": ["Java", "C++", "Python"] 
    } 
}

Let's read the input JSON as JsonNode and compare:

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

It's important to know that two list elements are only compared as equal if they have the same values in the exact same order.

4. Compare Two JSON Objects With a Custom Comparator

JsonNode.equals works quite well in most cases. Jackson also provides JsonNode.equals(comparator, JsonNode) to configure a custom Java Comparator object.

Let's understand how to use a custom Comparator.

4.1. Custom Comparator to Compare Numeric Values

Let's look at how to use a custom Comparator to compare two JSON elements having numeric values.

We'll use this JSON as input s1:

{
    "name": "John",
    "score": 5.0
}

Let's compare with another JSON defined as s2:

{
    "name": "John",
    "score": 5
}

We need to observe that the values of attribute score in inputs s1 and s2 are not the same.

Let's read the input JSON as JsonNode and compare:

JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);

assertNotEquals(actualObj1, actualObj2);

Notice that the two objects are not equal. The standard equals() method considers values 5.0 and 5 as different.

However, we can use a custom Comparator to compare values 5 and 5.0 and treat them as equal.

Let's first create a Comparator to compare two NumericNode objects:

public class NumericNodeComparator implements Comparator<JsonNode> 
{
    @Override
    public int compare(JsonNode o1, JsonNode o2)
    {
        if (o1.equals(o2)){
           return 0;
        }
        if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)){
            Double d1 = ((NumericNode) o1).asDouble();
            Double d2 = ((NumericNode) o2).asDouble(); 
            if (d1.compareTo(d2) == 0) {
               return 0;
            }
        }
        return 1;
    }
}

Next, let's see how to use this Comparator:

NumericNodeComparator cmp = new NumericNodeComparator();
assertTrue(actualObj1.equals(cmp, actualObj2));

4.2. Custom Comparator to Compare Text Values

Let's see another example of a custom Comparator for a case-insensitive comparison of two JSON values.

We'll use this JSON as input s1:

{
    "name": "john", 
    "score": 5 
}

Let's compare with another JSON defined as s2:

{ 
    "name": "JOHN", 
    "score": 5 
}

As we can see, the attribute name is lowercase in input s1 and uppercase in s2.

Let's first create a Comparator to compare two TextNode objects:

public class TextNodeComparator implements Comparator<JsonNode> 
{
    @Override
    public int compare(JsonNode o1, JsonNode o2) {
        if (o1.equals(o2)) {
            return 0;
        }
        if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
            String s1 = ((TextNode) o1).asText();
            String s2 = ((TextNode) o2).asText();
            if (s1.equalsIgnoreCase(s2)) {
                return 0;
            }
        }
        return 1;
    }
}

Let's see how to compare s1 and s2 using TextNodeComparator:

JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);

TextNodeComparator cmp = new TextNodeComparator();

assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));

Finally, we can see using a custom comparator object while comparing two JSON objects can be very useful when the input JSON element value is not exactly the same but we still want to treat them as equal.

5. Conclusion

In this quick article, we've seen how to use Jackson to compare two JSON objects and use a custom comparator

As always, the full source code of all the examples discussed here can be found over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Jackson footer banner
Comments are closed on this article!