循环以在 JAVA 中的 JSONObject 内获取相同的对象 N 次

Posted

技术标签:

【中文标题】循环以在 JAVA 中的 JSONObject 内获取相同的对象 N 次【英文标题】:Loop to get same object N time inside JSONObject in JAVA 【发布时间】:2021-03-25 21:07:14 【问题描述】:

如何将此响应解析为ArrayList。我有包含对象列表的层次结构数组,在每个对象中,当我将 type 作为“组”时,JSONArray 将作为“内容”,在 JSONArray 内我可以得到 n 不。的对象。每个对象可能包含类型为“组”。 如何解析并保存在ArrayList

hierarchy: 
[
   
   "id":"5fd1b4384f5ee9964099b6b0",
   "name":"Dev_5 Category Group `",
   "type":"group",
   "contents":[
      
         "id":"5fd1b4384f5ee9964099b6af",
         "name":"Dev_5 Parent Category Group 1",
         "type":"group",
         "contents":[
            
               "id":"5fd1b567505ee9af3a7a65c8",
               "name":"Dev_5 Parent Category Group 2",
               "type":"group",
               "contents":[
                  
                     "id":"5fd1b4384f5ee9964099b6b1",
                     "type":"category"
                  
               ],
               "desc":"",
               "image":""
            
         ],
         "desc":"",
         "image":""
      ,
      
         "id":"5fd1b57b4f5ee9114599b679",
         "type":"category"
      
   ],
   "desc":"",
   "image":""
  ,

----
,

---

]

代码

for (int i = 0; i < hierarchyArray.length(); i++) 
 
   hierarchyItemList.clear(); 
   JSONObject obj = hierarchyArray.optJSONObject(i); 
   JSONArray contentArray = obj.optJSONArray("contents"); 
   HierarchyItem item = new HierarchyItem(); 
   item.setId(obj.optString("id")); 
   item.setType(obj.optString("type")); 
   item.setGroupName(obj.optString("name")); 
   if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && 
   contentArray.length() > 0)  
         hierarchyItemList.clear(); 
         for (int j = 0; j < contentArray.length(); j++) 
          
              hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j))); 
          
   item.setContentList(hierarchyItemList); 
    
   if (obj.optString("type").equalsIgnoreCase("category") || 
   (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && 
   contentArray.length() > 0))  
      itemList.add(item); 
   


    private static HierarchyItem hierarchyJSON(JSONObject obj) 
        HierarchyItem item = new HierarchyItem();

        item.setId(obj.optString("id"));
        item.setType(obj.optString("type"));
        item.setGroupName(obj.optString("name"));
        JSONArray contentArray = obj.optJSONArray("contents");
        List<HierarchyItem> hierarchyItemList = new ArrayList<>();

        if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && contentArray.length() > 0) 
            hierarchyItemList.clear();
            for (int j = 0; j < contentArray.length(); j++) 
                hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
            
            item.setContentList(hierarchyItemList);
        

        return item;
    

使用上面的代码,最后一项更新为ArrayList中的所有项。如何解决这个问题。 提前致谢。

【问题讨论】:

【参考方案1】:

您已清除每个循环中的值列表,因此现有数据将被清除,并且列表中的新值将在您使用递归循环时更新。我已经删除了列表值的 clear() 并在循环开始时再次初始化。这将解决您的问题。

for (int i = 0; i < hierarchyArray.length(); i++) 



//hierarchyItemList.clear(); --> Remove this clear() method, it will clear your existing values
   JSONObject obj = hierarchyArray.optJSONObject(i); 
   JSONArray contentArray = obj.optJSONArray("contents"); 
   HierarchyItem item = new HierarchyItem(); 
   item.setId(obj.optString("id")); 
   item.setType(obj.optString("type")); 
   item.setGroupName(obj.optString("name")); 
   if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && 
   contentArray.length() > 0)  
         //hierarchyItemList.clear(); 
         hierarchyItemList = new ArrayList<>(); // instead of clear the list, initialize it as new list, then it will keep existing list values and load new data in new list
         for (int j = 0; j < contentArray.length(); j++) 
          
              hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j))); 
          
   item.setContentList(hierarchyItemList); 
    
   if (obj.optString("type").equalsIgnoreCase("category") || 
   (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && 
   contentArray.length() > 0))  
      itemList.add(item); 
   


    private static HierarchyItem hierarchyJSON(JSONObject obj) 
        HierarchyItem item = new HierarchyItem();

        item.setId(obj.optString("id"));
        item.setType(obj.optString("type"));
        item.setGroupName(obj.optString("name"));
        JSONArray contentArray = obj.optJSONArray("contents");
        List<HierarchyItem> hierarchyItemList = new ArrayList<>();

        if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && contentArray.length() > 0) 
            hierarchyItemList.clear();
            for (int j = 0; j < contentArray.length(); j++) 
                hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
            
            item.setContentList(hierarchyItemList);
        

        return item;
    

【讨论】:

【参考方案2】:

如果 hierarchyItemList 是您的结果列表,则不应在多个位置清除它,而应仅在最开始时清除它。

这是一个干净的版本

public class JsonDemo 
  public static void main(String[] args) throws Exception 
    String jsonString = new String(Files.readAllBytes(Paths.get("test.json")), StandardCharsets.UTF_8);
    JSONArray hierarchyJsonArray = new JSONArray(jsonString);
    List<HierarchyItem> hierarchyItemList = new ArrayList<>();
    for(int i = 0; i < hierarchyJsonArray.length(); i++) 
      HierarchyItem hierarchyItem = parseItem(hierarchyJsonArray.getJSONObject(i));
      hierarchyItemList.add(hierarchyItem);
    
  

  private static HierarchyItem parseItem(JSONObject jsonObject) 
    HierarchyItem hierarchyItem = new HierarchyItem();
    hierarchyItem.id = jsonObject.optString("id", "");
    hierarchyItem.type = jsonObject.optString("type", "");
    hierarchyItem.name = jsonObject.optString("name", "");
    hierarchyItem.desc = jsonObject.optString("desc", "");
    hierarchyItem.image = jsonObject.optString("image", "");

    // not even checking for type=group, if there is a contents array, parse it
    JSONArray contentsArray = jsonObject.optJSONArray("contents");
    if(contentsArray != null) 
      for(int i = 0; i < contentsArray.length(); i++) 
        // recursive call
        HierarchyItem childItem = parseItem(contentsArray.getJSONObject(i));
        hierarchyItem.contents.add(childItem);
      
    

    return hierarchyItem;
  


class HierarchyItem 
  public String              id       = "";
  public String              type     = "";
  public String              name     = "";
  public String              desc     = "";
  public String              image    = "";
  public List<HierarchyItem> contents = new ArrayList<>();

test.json:

[
    
        "id": "5fd1b4384f5ee9964099b6b0",
        "name": "Dev_5 Category Group `",
        "type": "group",
        "contents": [
            
                "id": "5fd1b4384f5ee9964099b6af",
                "name": "Dev_5 Parent Category Group 1",
                "type": "group",
                "contents": [
                    
                        "id": "5fd1b567505ee9af3a7a65c8",
                        "name": "Dev_5 Parent Category Group 2",
                        "type": "group",
                        "contents": [
                            
                                "id": "5fd1b4384f5ee9964099b6b1",
                                "type": "category"
                            
                        ],
                        "desc": "",
                        "image": ""
                    
                ],
                "desc": "",
                "image": ""
            ,
            
                "id": "5fd1b57b4f5ee9114599b679",
                "type": "category"
            
        ],
        "desc": "",
        "image": ""
    ,
    
        "id": "id2",
        "type": "category"
    ,
    
        "id": "id3",
        "type": "category"
    
]

【讨论】:

我需要一个递归调用,因为对象的这个 id "5fd1b4384f5ee9964099b6b1" 也可能包含类型:"group"。那就是问题所在。最多可以是 'n' 时间。 是吗?我什至用注释标记了递归调用。 嗯,也许你以为我把它注释掉了。让我改变它。 让我检查一下这个@Reto

以上是关于循环以在 JAVA 中的 JSONObject 内获取相同的对象 N 次的主要内容,如果未能解决你的问题,请参考以下文章

我想将 JSONObject 放入 JSONArray 内 for 循环

android怎么遍历jsonobject

对于表中的行,将行保存在临时表中以在 plpgsql 的选择查询中使用其数据

循环内变量的类转换

jsonobject如何获取一个集合里的某个对象所有属性的值

json中怎么获取key