知識庫 / JSON RSS 訂閱

獲取 JSONObject 中的值

JSON
HongKong
6
09:48 PM · Dec 05 ,2025

1. 引言

本教程將深入探討如何從 JSONObject 實例中獲取值。

對於 Java 中 JSON 支持的總體介紹,請參閲 JSON-Java 的介紹。

2. <em>JSONObject</em> 結構

<em>JSONObject</em> 是一種類似於映射的數據結構。它將數據存儲為一組鍵值對。雖然鍵的類型為String,但值可以是多種類型。此外,值類型可以是原始類型或複合類型。原始類型包括StringNumberBoolean類型,或JSONObject.NULL對象。複合類型包括JSONObjectJSONArray` 類型。因此,JSON 數據可能具有任意的複雜度和嵌套結構。

由於嵌套結構中獲取值需要付出更多努力。從現在開始,讓我們參考以下一個虛構員工的 JSON 數據:

{
  "name" : "Bob",
  "profession" : "Software engineer",
  "department" : "Research",
  "age" : 40,
  "family" : [
    {
      "wife" : {
        "name" : "Alice",
        "profession" : "Doctor",
        "age" : 38
      }
    },
    {
      "son" : {
        "name" : "Peter",
        "occupation" : "Schoolboy",
        "age" : 11
      }
    }
  ],
  "performance" : [
    {
      "2020" : 4.5
    },
    {
      "2021" : 4.8
    }
  ]
}

3. JSONObject 的 Getter 方法

首先,讓我們看看 JSONObject 類提供的 Getter API。 共有兩組方法——get()opt() 方法。 這兩組方法的主要區別在於,get() 方法在找不到鍵時會拋出異常,而 opt() 方法不會拋出異常,並根據方法返回 null 或特定值。

此外,每組方法包含一個通用方法和幾個帶有類型轉換的特定方法。 通用方法返回一個 Object 實例,而特定方法返回一個已轉換的實例。 讓我們使用通用 get() 方法獲取 JSON 數據中的“family”字段。 我們假設 JSON 數據已經預先加載到 jsonObject 變量中,該變量的類型為 JSONObject

    JSONArray family = (JSONArray) jsonObject.get("family");

我們也可以用更易讀的方式,通過使用針對 JSONArray 的特定獲取器來實現:

    JSONArray family = jsonObject.getJSONArray("family");

4. 直接獲取值

在這種方法中,我們通過獲取從目標值到中間值的每個路徑上的值來直接獲取值。 下面的代碼演示瞭如何直接獲取員工的兒子姓名:

    JSONArray family = jsonObject.getJSONArray("family");
    JSONObject sonObject = family.getJSONObject(1);
    JSONObject sonData = sonObject.getJSONObject("son");
    String sonName = sonData.getString("name");
    Assertions.assertEquals(sonName, "Peter");

如我們所見,直接獲取值的方法存在侷限性。首先,我們需要了解 JSON 數據結構的精確信息。其次,我們需要了解每個值的具體數據類型,以便正確使用 JSONObject 的獲取方法。

此外,在 JSON 數據結構動態時,需要在代碼中添加全面的檢查。例如,對於所有 get() 方法,都需要使用 try-catch 塊將代碼包裹起來。 此外,對於 opt() 方法,需要添加空值或特定值檢查。

5. 遞歸獲取值

與 JSON 數據中獲取值的遞歸方法相比,遞歸方法更靈活且不易出錯。在實現此方法時,我們需要考慮 JSON 數據的嵌套結構。

首先,當值的鍵類型為 JSONObjectJSONArray 時,我們需要將遞歸搜索向下傳遞到該值。其次,當在當前遞歸調用中找到鍵時,無論值類型為原始類型還是其他類型,都需要將其映射值添加到返回結果中。

以下方法實現了遞歸搜索:

    public List<String> getValuesInObject(JSONObject jsonObject, String key) {
        List<String> accumulatedValues = new ArrayList<>();
        for (String currentKey : jsonObject.keySet()) {
            Object value = jsonObject.get(currentKey);
            if (currentKey.equals(key)) {
                accumulatedValues.add(value.toString());
            }

            if (value instanceof JSONObject) {
                accumulatedValues.addAll(getValuesInObject((JSONObject) value, key));
            } else if (value instanceof JSONArray) {
                accumulatedValues.addAll(getValuesInArray((JSONArray) value, key));
            }
        }

        return accumulatedValues;
    }

    public List<String> getValuesInArray(JSONArray jsonArray, String key) {
        List<String> accumulatedValues = new ArrayList<>();
        for (Object obj : jsonArray) {
            if (obj instanceof JSONArray) {
                accumulatedValues.addAll(getValuesInArray((JSONArray) obj, key));
            } else if (obj instanceof JSONObject) {
                accumulatedValues.addAll(getValuesInObject((JSONObject) obj, key));
            }
        }

        return accumulatedValues;
    }

為了簡化問題,我們提供了兩種單獨的方法:一種用於在 JSONObject 中進行遞歸搜索,另一種則在 JSONArray 實例中進行操作。 JSONObject 是一種類似於映射的數據結構,而 JSONArray 是一種類似於數組的數據結構。因此,它們的迭代方式不同。因此,將所有邏輯放在一個方法中會使代碼變得複雜,需要進行類型轉換和 if-else 分支。

最後,讓我們為 getValuesInObject() 方法編寫測試代碼:

    @Test
    public void getAllAssociatedValuesRecursively() {
        List<String> values = jsonObjectValueGetter.getValuesInObject(jsonObject, "son");
        Assertions.assertEquals(values.size(), 1);

        String sonString = values.get(0);
        Assertions.assertTrue(sonString.contains("Peter"));
        Assertions.assertTrue(sonString.contains("Schoolboy"));
        Assertions.assertTrue(sonString.contains("11"));

        values = jsonObjectValueGetter.getValuesInObject(jsonObject, "name");
        Assertions.assertEquals(values.size(), 3);

        Assertions.assertEquals(values.get(0), "Bob");
        Assertions.assertEquals(values.get(1), "Alice");
        Assertions.assertEquals(values.get(2), "Peter");
    }

6. 結論

在本文中,我們討論瞭如何在 JSONObject 中獲取值。

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

發佈 評論

Some HTML is okay.