Iterating Over an Instance of org.json.JSONObject – 遍历org.json.JSONObject的一个实例

最后修改: 2019年 2月 22日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this tutorial, we’ll look at a couple of approaches for iterating over a JSONObject, a simple JSON representation for Java.

在本教程中,我们将看看在JSONObject上迭代的几种方法,这是一种用于Java的简单JSON表示法。

We’ll start with a naive solution and then look at something a little more robust.

我们将从一个天真的解决方案开始,然后再看一些更强大的东西。

2. Iterating Through a JSONObject

2.通过JSONObject进行迭代

Let’s start with the simple case of iterating a JSON of name-value pairs:

让我们从迭代名-值对的JSON的简单情况开始。

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

For this, we can simply iterate through the keys using the keys() method:

为此,我们可以简单地使用keys()方法来迭代键值:

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

And our output will be:

而我们的产出将是。

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

3. Traversing Through a JSONObject

3.遍历一个JSONObject

But let’s say that we have a more complex structure:

但是,假设我们有一个更复杂的结构。

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

What does iterating through the keys mean in this case?

在这种情况下,通过键的迭代是什么意思?

Let’s take a look at what our naive keys() approach would give us:

让我们看看我们天真的keys() 方法会给我们带来什么。

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

This, perhaps, isn’t quite as helpful. It seems like what we want in this case is not iteration, but instead traversal.

这一点,也许并不十分有用。在这种情况下,我们想要的似乎不是迭代,而是遍历。

Traversing through a JSONObject is different from iterating through a JSONObject‘s key set.

遍历一个JSONObject与遍历一个JSONObject的键集不同。

For this, we actually need to check the value type, too. Let imagine we do this in a separate method:

为此,我们实际上也需要检查值的类型。让我们想象一下,我们在一个单独的方法中做这个。

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

Then, our approach is still fairly similar:

那么,我们的方法仍然相当类似。

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

The only thing is that we need to think about how to handle arrays.

唯一的问题是,我们需要考虑如何处理数组。

4. Traversing Through a JSONArray

4.遍历一个JSONArray

Let’s try and keep a similar approach of using an iterator. Instead of calling keys(), though, we’ll call iterator():

让我们尝试保持类似的使用迭代器的方法。不过,我们将调用keys(),而不是调用iterator()

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

Now, this solution is limiting because we are combining traversal with the action we want to take. A common approach to separating the two would be using the Visitor pattern.

现在,这种解决方案具有局限性,因为我们正在将遍历与我们想要采取的行动相结合。将这两者分开的常见方法是使用visitor 模式

5. Conclusion

5.总结

In this article, we saw a way to iterate over a JSONObject for simple name-value pairs, the problem associated with complex structures, and a traversal technique to solve it.

在这篇文章中,我们看到了一种在JSONObject上迭代简单的名-值对的方法,与复杂结构相关的问题,以及解决这个问题的遍历技术。

Of course, this was a depth-first traversal method, but we could do breadth-first in a similar way.

当然,这是一种深度优先的遍历方法,但我们也可以用类似的方式进行广度优先

The complete code for the example is available over on Github.

该示例的完整代码可在Github上获得