1. 序章

このチュートリアルでは、Javaの単純なJSON表現であるJSONObjectを反復処理するためのいくつかのアプローチを見ていきます。

単純なソリューションから始めて、もう少し堅牢なものを見ていきます。

2. JSONObjectを反復処理します

名前と値のペアのJSONを反復する単純なケースから始めましょう。

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

このために、keys()メソッドを使用してキーを単純に反復することができます:

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()アプローチが私たちに何を与えるかを見てみましょう:

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

これは、おそらく、それほど役に立ちません。 この場合に必要なは反復ではなく、トラバーサルのようです。

JSONObject をトラバースすることは、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つを分離するための一般的なアプローチは、ビジターパターンを使用することです。

5. 結論

この記事では、 JSONObject を反復処理して、単純な名前と値のペア、複雑な構造に関連する問題、およびそれを解決するためのトラバーサル手法について説明しました。

もちろん、これは深さ優先探索法でしたが、同様の方法で幅優先を実行できました。

この例の完全なコードは、Githubから入手できます。