1. 简介

在本篇文章中,我们将介绍几种在 Java 中处理 JSONObject(来自 org.json 包)的常见方式。

我们会从一个最基础的实现讲起,然后逐步升级到更健壮、更通用的方案。如果你在项目中经常跟 JSON 打交道,这篇文章应该能帮你踩掉不少坑 ✅

2. 遍历简单的 JSONObject

我们先从最简单的场景入手:一个只包含键值对的 JSON 对象:

{
  "name": "Cake",
  "cakeId": "0001",
  "cakeShape": "Heart"
}

对于这种结构,我们可以直接使用 keys() 方法来获取所有的 key:

void handleJSONObject(JSONObject jsonObject) {
    jsonObject.keys().forEachRemaining(key -> {
        Object value = jsonObject.get(key);
        logger.info("Key: {0}\tValue: {1}", key, value);
    });
}

输出结果如下:

Key: name      Value: Cake
Key: cakeId    Value: 0001
Key: cakeShape Value: Heart

这个方法简单粗暴,适用于只有一层结构的 JSON。

3. 遍历嵌套结构的 JSONObject

但如果 JSON 结构复杂一些呢?比如下面这个:

{
  "batters": [
    {
      "type": "Regular",
      "id": "1001"
    },
    {
      "type": "Chocolate",
      "id": "1002"
    },
    {
      "type": "BlueBerry",
      "id": "1003"
    }
  ],
  "name": "Cake",
  "cakeId": "0001"
}

这时候再用 keys() 方法遍历,结果可能是这样的:

Key: batters    Value: [{"type":"Regular","id":"1001"},{"type":"Chocolate","id":"1002"},
  {"type":"BlueBerry","id":"1003"}]
Key: name       Value: Cake
Key: cakeId     Value: 0001

显然,这种输出对处理嵌套结构没啥用 ❌。我们需要的不是“遍历 key”,而是“递归遍历整个结构”。

所以,我们得检查每个 value 的类型,并递归处理:

void handleValue(Object value) {
    if (value instanceof JSONObject) {
        handleJSONObject((JSONObject) value);
    } else if (value instanceof JSONArray) {
        handleJSONArray((JSONArray) value);
    } else {
        logger.info("Value: {0}", value);
    }
}

然后我们原来的 handleJSONObject 方法就可以这样改写:

void handleJSONObject(JSONObject jsonObject) {
    jsonObject.keys().forEachRemaining(key -> {
        Object value = jsonObject.get(key);
        logger.info("Key: {0}", key);
        handleValue(value);
    });
}

⚠️ 注意:这里我们还需要处理 JSONArray 的情况。

4. 遍历 JSONArray

处理数组结构时,我们可以继续使用迭代器的方式。只不过这次不是调用 keys(),而是使用 iterator()

void handleJSONArray(JSONArray jsonArray) {
    jsonArray.iterator().forEachRemaining(element -> {
        handleValue(element);
    });
}

不过这种写法有个缺点:把遍历逻辑和业务处理混在一起了。如果想更优雅地处理,推荐使用 Visitor 模式 来解耦。

5. 总结

在这篇文章中,我们介绍了如何遍历 JSONObject

  • 对于简单的键值对结构,使用 keys() 即可 ✅
  • 如果结构嵌套较深,需要递归处理,分别判断是 JSONObject 还是 JSONArray
  • 遍历数组时推荐使用 iterator()
  • 如果逻辑复杂,建议使用设计模式(如 Visitor)来解耦遍历与处理逻辑

当然,我们这里实现的是深度优先(depth-first)遍历,广度优先(breadth-first)也是可以做到的,只是应用场景相对较少。


📌 小贴士:虽然 org.json 包简单好用,但在大型项目中建议使用更强大的库,如 Jackson 或 Gson,它们提供了更完善的遍历和解析能力。


原始标题:Iterating Over an Instance of org.json.JSONObject | Baeldung