【问题标题】:Convert nested JsonArray in Map Java在 Map Java 中转换嵌套的 JsonArray
【发布时间】:2026-01-01 06:15:01
【问题描述】:

我正在尝试编写一个通用代码,例如下面的 JSON 数组可以转换为地图。

这是示例。 其中父元素是菜单

{"menu": {    
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},        
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},            
        {"id": "Quality"},
        {"id": "Pause"}
    ]
}}

将地图值映射为:

menu.items_0.id=open    
menu.items_1.id=OpenNew
menu.items_1.label=Open New    
menu.items_2.id=ZoomIn
menu.items_2.label=Zoom In    
menu.items_3.id=ZoomOut
menu.items_3.id=Zoom Out    
menu.items_4.id=Quality    
menu.items_5.id=Pause

【问题讨论】:

标签: java arrays json hashmap


【解决方案1】:

对于我的回答,您需要这些课程:

org.json.JSONArray;
org.json.JSONException;
org.json.JSONObject;

我假设这样的课程:

public class menu{
    private String id;
    private String label;
}

解析-如果它是流、文件等,我将忽略它-。但是,它假定您已操作源以创建一个名为 myString 的长字符串对象。

JSONObject topLevel = new JSONObject( myString );
JSONObject itemsArray= topLevel.getJSONArray("items");

int tempID;
String tempLabel;

//Now go through all items in array.
for(int i =0; i < itemsArray.length(); i++){
    tempID = itemsArray.getJSONObject(i).getString("id");

    if(itemsArray.getJSONObject(i).has("label"))
        tempLabel = itemsArray.getJSONObject(i).getString("label");
    else
        tempLabel = null;

    //whatever action you need to take
    menu = new menu( tempId, tempLabel);
}

【讨论】:

  • 我之前也有同样的想法,但我想要一个通用代码,它可以与元素名称无关。
  • 我使用了一个 HashMap 类,我认为它以类似的方式运行,因为它实现了 Map 接口。我会这样工作:
【解决方案2】:

这里的代码可以完成工作。你可以提取一些方法,或者稍微重构一下,但它应该可以解决问题。

public class Example {

    public static void main(String[] args) {

        String source = "{\"menu\": {\"items\": [{\"id\": \"Open\"},{\"id\": \"OpenNew\", \"label\": \"Open New\"}, " +
                "{\"id\": \"ZoomIn\", \"label\": \"Zoom In\"},"
                + "{\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"},{\"id\": \"Quality\"},{\"id\": \"Pause\"}"
                + "]}}";

        JSONObject jsonObject = new JSONObject(source);

        Map<String, Object> map = jsonObject.toMap();

        Map<String, String> resultMap = new HashMap<>();

        map
                .entrySet()
                .forEach(entry -> addToResult(entry, resultMap, "", ""));

        System.out.println(resultMap);

    }

    private static void addToResult(Map.Entry<String, Object> entry, Map<String, String> resultMap, String fieldNameAcummulator, String index) {
        Object value = entry.getValue();
        if (!Map.class.isAssignableFrom(value.getClass()) && !List.class.isAssignableFrom(value.getClass())) {
            resultMap.put(addToAccumulator(entry, fieldNameAcummulator, index), (String) value);
            return;
        }

        if (Map.class.isAssignableFrom(value.getClass())) {
            Map<String, Object> nestedMap = (HashMap<String, Object>) value;
            nestedMap
                    .entrySet()
                    .forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), ""));
        } else {
            List<HashMap<String, Object>> hashMaps = (List<HashMap<String, Object>>) value;
            IntStream.range(0, hashMaps.size())
                    .forEach(listIndex -> {
                        HashMap<String, Object> nestedMap = hashMaps.get(listIndex);
                        nestedMap.entrySet().forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), String.valueOf(listIndex)));
                    });
        }
    }

    private static String addToAccumulator(Map.Entry<String, Object> entry, String fieldNameAcummulator, String index) {
        return fieldNameAcummulator.isEmpty()
                ? entry.getKey()
                : fieldNameAcummulator + getKeyValueWithIndex(entry, index);
    }

    private static String getKeyValueWithIndex(Map.Entry<String, Object> entry, String index) {
        return index.isEmpty()
                ? ".".concat(entry.getKey())
                : "_".concat(index).concat(".").concat(entry.getKey());
    }
}

如果您对实施有任何疑问,请随时询问。

希望对你有帮助!

【讨论】:

    【解决方案3】:

    我改变了一些逻辑,之后它就可以正常工作了。

    import com.google.gson.JsonArray;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import org.json.JSONArray;
    import org.json.JSONObject;
    
    public class JsonToMapConvertor {
    
        private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
        public static JsonParser parser = new JsonParser();
    
        public static void main(String[] args) throws Exception{
    
        String json ="{\n" +
    "    \"glossary\": {\n" +
    "        \"title\": \"example glossary\",\n" +
    "       \"GlossDiv\": {\n" +
    "            \"title\": \"S\",\n" +
    "           \"GlossList\": {\n" +
    "                \"GlossEntry\": {\n" +
    "                    \"ID\": \"SGML\",\n" +
    "                   \"SortAs\": \"SGML\",\n" +
    "                   \"GlossTerm\": \"Standard Generalized Markup Language\",\n" +
    "                   \"Acronym\": \"SGML\",\n" +
    "                   \"Abbrev\": \"ISO 8879:1986\",\n" +
    "                   \"GlossDef\": {\n" +
    "                        \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n" +
    "                       \"GlossSeeAlso\": [\"GML\", \"XML\"]\n" +
    "                    },\n" +
    "                   \"GlossSee\": \"markup\"\n" +
    "                }\n" +
    "            }\n" +
    "        }\n" +
    "    }\n" +
    "}";
    
           HashMap<String, Object> map = createHashMapFromJsonString(json,""); 
            System.out.println("map size "+map.size());
    
            for (Map.Entry<String, Object> entry : map.entrySet()) {            
              if(!entry.getValue().toString().contains("{"))  
                    System.out.println(entry.getKey()+" : "+entry.getValue());
            }
    
        }
    
    public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) throws Exception{   
    
        if(json.startsWith("[",0)){        
            JSONArray jsonArray = new JSONArray(json);    
                for (int i = 0; i < jsonArray.length(); i++){
                    JSONObject jsonobject = jsonArray.getJSONObject(i);               
                    createHashMapFromJsonString(jsonobject.toString(), prefix+"_"+i);
                }        
        }    
        else{
    
            JsonObject object = (JsonObject) parser.parse(json);   
            Set<Map.Entry<String, JsonElement>> set = object.entrySet();
            Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
            while (iterator.hasNext()) {
    
                Map.Entry<String, JsonElement> entry = iterator.next(); 
                String key = entry.getKey();
    
                if(prefix.length()!=0){
                    key = prefix + "."+key;
                }
    
                JsonElement value = entry.getValue();
                if (null != value) {            
                    if (!value.isJsonPrimitive()) {
                        if (value.isJsonObject()) {                        
                            mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
                        } else if (value.isJsonArray() && value.toString().contains(":")) {
    
                            List<HashMap<String, Object>> list = new ArrayList<>();
                            JsonArray array = value.getAsJsonArray();
                            if (null != array) {
                                for (JsonElement element : array) {                               
                                    if (!element.isJsonPrimitive()) {
                                           createHashMapFromJsonString(value.toString(),key);
                                    }else{
                                        list.add(createHashMapFromJsonString(value.toString(),key));
                                        }
                                    }                 
                                mapReturn.put(key, list);
                            }
                        } else if (value.isJsonArray() && !value.toString().contains(":")) {                    
                            mapReturn.put(key, value.getAsJsonArray());
                        }              
                    } else {
                        mapReturn.put(key, value.getAsString());
                    }
                }
            }
        }
        return mapReturn;
      }
    }
    

    【讨论】:

      【解决方案4】:

      将 JSONObject 转换为通用映射列表的另一种方法

      public static List<Map<String, Object>> getJsonNode(String jsonContents, String nodeName)
              throws JsonProcessingException, IOException, ParseException {
          JSONParser parser = new JSONParser();
          JSONObject json = (JSONObject) parser.parse(jsonContents);
      
          Object o = json.get(nodeName);
          List<Map<String, Object>> results = Lists.newArrayList();
      
          if (o instanceof JSONObject) {
              results.add((Map<String, Object>) o);
          } else if (o instanceof JSONArray) {
              List<Map<String, Object>> hashMaps = (List<Map<String, Object>>) o;
              results.addAll((Collection<? extends Map<String, Object>>) hashMaps);
          }
          return results;
      }
      
      /**
       * Driver
       * 
       * @param args
       * @throws IOException
       * @throws ParseException
       */
      public static void main(String[] args) throws IOException, ParseException {
          String jsonInputFile = "temp/input.json";
          String jsonContents = new String(Files.readAllBytes(Paths.get(jsonInputFile)));
      
          List<Map<String, Object>> results = getJsonNode(jsonContents, "summary");
          for (Map<String, Object> entry : results) {
              System.out.println(entry);
          }
          ///////////////////////////////////////
          results = getJsonNode(jsonContents, "payWay");
          for (Map<String, Object> entry : results) {
              System.out.println(entry);
          }
          ///////////////////////////////////////
          results = getJsonNode(jsonContents, "sellerDetails");
          for (Map<String, Object> entry : results) {
              System.out.println(entry);
          }
      }
      

      【讨论】: