知識庫 / JSON / Jackson RSS 訂閱

使用 Jackson 比較兩個 JSON 對象

Data,Jackson
HongKong
5
09:53 PM · Dec 05 ,2025

1. 概述

在本教程中,我們將探討如何使用 Jackson(一個用於 Java 的 JSON 處理庫)比較兩個 JSON 對象。

2. Maven 依賴

首先,讓我們添加 jackson-databind Maven 依賴:

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

3. 使用 Jackson 比較兩個 JSON 對象

我們將使用 ObjectMapper 類來讀取一個對象作為 JsonNode

讓我們創建一個 ObjectMapper

ObjectMapper mapper = new ObjectMapper();

3.1. 比較兩個簡單的 JSON 對象

讓我們首先使用 <a href="https://static.javadoc.io/com.fasterxml.jackson.core/jackson-databind/2.9.8/com/fasterxml/jackson/databind/JsonNode.html#equals-java.lang.Object-"><em >JsonNode.equals</em></a> 方法。<strong ><em>equals()</em></strong > 方法執行一個完整的(深層)比較。

假設我們有一個 JSON 字符串,定義為 <em >s1</em></em > 變量:

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

我們想將其與另一個JSON進行比較,即 s2

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

讓我們讀取輸入 JSON 數據作為 JsonNode 進行比較:

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

需要注意的是,儘管輸入 JSON 變量 s1s2 的屬性順序不相同,但 equals() 方法會忽略順序並將其視為相等。

3.2. 比較具有嵌套元素的兩個 JSON 對象

接下來,我們將學習如何比較具有嵌套元素的兩個 JSON 對象。

讓我們從以下 JSON 對象開始,定義為 s1 變量:

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

如我們所見,JSON 包含一個嵌套的元素 contact

我們希望將其與另一個由 s2 定義的 JSON 進行比較。

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

讓我們讀取輸入 JSON 作為 JsonNode 並進行比較:

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

再次強調,equals() 也可以比較兩個包含嵌套元素的 JSON 對象。

3.3. 比較包含列表元素的兩個 JSON 對象

同樣,我們也可以比較包含列表元素的兩個 JSON 對象。

讓我們考慮以下 JSON 定義為 s1

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

我們正在將其與另一個JSON進行比較,s2:

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

讓我們讀取輸入 JSON 作為 JsonNode 並進行比較:

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

重要的是要知道,兩個列表元素只有在它們具有完全相同的順序和值時才被視為相等。

4. 使用自定義比較器比較兩個 JSON 對象

`JsonNode.equals 在大多數情況下都非常實用。Jackson 還提供了 JsonNode.equals(comparator, JsonNode) 方法,用於配置自定義的 Java Comparator 對象。

讓我們瞭解如何使用自定義 Comparator

4.1. 自定義比較器用於比較數值

讓我們看看如何使用自定義 Comparator 來比較具有數值值的兩個 JSON 元素。

我們將使用以下 JSON 作為輸入 s1

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

讓我們與另一個 JSON 定義為 s2 進行比較:

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

我們需要注意到 輸入 s1s2 中屬性 score 的值不相同。

讓我們將輸入 JSON 讀取為 JsonNode 並進行比較。

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

assertNotEquals(actualObj1, actualObj2);

請注意,這兩個對象不相等。標準 equals() 方法將 5.0 和 5 視為不同的值。

但是,我們可以使用自定義 Comparator 來比較 5 和 5.0,並將它們視為相等。

讓我們首先創建一個 Comparator,用於比較兩個 NumericNode 對象:

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

接下來,讓我們看看如何使用這個比較器

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

4.2. 自定義比較器用於比較文本值

讓我們來看另一個 自定義 比較器 的示例,用於對兩個 JSON 值進行不區分大小寫的比較。

我們將使用以下 JSON 作為輸入 s1

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

讓我們與另一個 JSON 定義為 s2 進行比較:

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

如我們所見,屬性 name 在輸入 s1 中為小寫,而在 s2 中為大寫。

我們首先創建一個 Comparator,用於比較兩個 TextNode 對象:

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

讓我們看看如何使用 TextNodeComparator 比較 s1s2

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

TextNodeComparator cmp = new TextNodeComparator();

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

最後,使用自定義比較器對象比較兩個 JSON 對象在某些情況下非常有用,即使輸入 JSON 元素的值不完全相同,但我們仍然希望將它們視為相等。

5. 結論

在本文中,我們學習瞭如何使用 Jackson 比較兩個 JSON 對象以及使用自定義比較器。 

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.