org.json.JSONObjectのインスタンスの繰り返し

1. 前書き

このチュートリアルでは、Javaの単純なJSON表現である_https://www.baeldung.com/java-org-json [JSONObject] _を反復処理するためのいくつかのアプローチを見ていきます。
素朴なソリューションから始めて、もう少し堅牢なものを見ていきます。

2. _JSONObject_を反復処理する

名前と値のペアのJSONを反復する単純なケースから始めましょう。
{
  "name": "Cake",
  "cakeId": "0001",
  "cakeShape": "Heart"
}
このために、_keys()_ method:*を使用してキーを単純に反復することができます:*
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

3. _JSONObject_のトラバース

しかし、より複雑な構造を持っているとしましょう:
{
  "batters": [
    {
      "type": "Regular",
      "id": "1001"
    },
    {
      "type": "Chocolate",
      "id": "1002"
    },
    {
      "type": "BlueBerry",
      "id": "1003"
    }
  ],
  "name": "Cake",
  "cakeId": "0001"
}
この場合、キーを反復処理することはどういう意味ですか?
素朴な__keys()__approachが私たちに与えるものを見てみましょう:
Key: batters    Value: [{"type":"Regular","id":"1001"},{"type":"Chocolate","id":"1002"},
  {"type":"BlueBerry","id":"1003"}]
Key: name       Value: Cake
Key: cakeId     Value: 0001
これは、おそらく、それほど有用ではありません。 この場合に必要なのは反復ではなく、トラバーサルです*。
_JSONObject_の走査は、is_JSONObject_のキーセットの反復とは異なります。
このためには、*実際に値の型もチェックする必要があります*。これを別のメソッドで行うことを想像してください。
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);
    }
}
それから、私たちのアプローチはまだかなり似ています:
void handleJSONObject(JSONObject jsonObject) {
    jsonObject.keys().forEachRemaining(key -> {
        Object value = jsonObject.get(key);
        logger.info("Key: {0}", key);
        handleValue(value);
    });
}
唯一のことは、配列の処理方法について考える必要があるということです。

4. _JSONArray_のトラバース

イテレータを使用する同様のアプローチを試してみましょう。 *ただし、_keys()_を呼び出す代わりに、_iterator()_を呼び出します:*
void handleJSONArray(JSONArray jsonArray) {
    jsonArray.iterator().forEachRemaining(element -> {
        handleValue(element)
    });
}
さて、このソリューションは、*トラバーサルと実行したいアクションを組み合わせているため、制限されています*。 2つを分離する一般的な方法は、link:/java-visitor-pattern[Visitor pattern]を使用することです。

5. 結論

この記事では、単純な名前と値のペア、複雑な構造に関連する問題、およびそれを解決するためのトラバーサル手法について、_JSONObject_を反復処理する方法を見ました。
もちろん、これは深さ優先の走査方法でしたが、同様の方法で幅優先*を行うことができました。
この例の完全なコードは、https://github.com/eugenp/tutorials/tree/master/json [Github上]で入手できます。