java - 使用 Lambda、Stream java 将值添加到两个嵌套的 JSON 数组中

标签 java json lambda nested

我对 Lambda 和流有点陌生。经过大量研究,我找不到解决我的问题的正确答案。但如果你知道任何相关答案,请给我链接,我会删除这个问题。谢谢。

我的问题是我尝试将以下代码转换为 Lambda。但因为我在嵌套循环中使用索引和验证,所以我无法使用 Lambda 将其转换为一个 block 代码(可能吗?)。 另外,如果有人提出以更好的方式编写此代码的建议,我将不胜感激。

for (int i = 0; i < list1.length(); i++) {
    if (list1.getJSONObject(i).has("owner")) {
        dataObject1 = list1.getJSONObject(i).getJSONObject("owner");
        if (GeneralUtils.isNameExist(inputNameOrSubject, dataObject1, true)) {
            if (usersList != null) {
                for (int j = 0; j < usersList.length(); j++) {
                    if (
                            GeneralUtils.isNameExist(usersList.getJSONObject(j).getString("first_name"), dataObject1, false) ||
                                    GeneralUtils.isNameExist(usersList.getJSONObject(j).getString("last_name"), dataObject1, false)
                    ) {
                        usersExist = true;
                        usersIndex = j;
                    }
                }
                if (usersExist) {
                    if (list1.getJSONObject(i).has("name")) {
                        topicName = list1.getJSONObject(i).getString("name");
                        topicListJA = usersList.getJSONObject(usersIndex).getJSONArray("topics");
                        topicExist = false;
                        for (int t = 0; t < topicListJA.length(); t++) {
                            if (topicName.toLowerCase().equals(topicListJA.getString(t).toLowerCase())) {
                                topicExist = true;
                                break;
                            }
                        }
                        if (!topicExist) {
                            usersList.getJSONObject(usersIndex).getJSONArray("topics").put(topicName);
                        }
                    }

                } else {
                    result = dataObject1;
                    result.put("topics", new JSONArray(new String[]{list1.getJSONObject(i).getString("name")}));
                    usersList.put(result);
                }
            } else if (list1.getJSONObject(i).has("name")) {
                result = dataObject1; 
                result.put("topics", new JSONArray(new String[]{list1.getJSONObject(i).getString("name")}));
                usersList = new JSONArray();
                usersList.put(result);
            }

        }

    }
}
return String.valueOf(usersList);

更新: 输入列表是一个 JSON 数组,如下所示:

[{
    owner: { 
          signature: "",
          created: "2019-08-26 02:14:15", 
          nickname: "",
          last_name: "Kennedy", 
          title: null,
          first_name: "Victor", 
          updated: "2019-11-24 20:58:57",
          email: "v.kennedy@gmail.com"
    },
     topics: [ 
          {
               id:"0"
               name: "topic 1"
          },{
               id:"1"
               name: "topic 2"
          },{
               id:"0"
               name: "topic 3"
          },
     ]
},

{    owner: {
          signature: "",
          created: "2014-03-25 23:51:48",
          nickname: "",
          last_name: "Kent", 
          title: "",
          first_name: "Bill", 
          updated: "2019-11-21 21:26:24",
          email: "bill.kent@gmail.com"
     },
     topics: [ 
          {
               id:"0"
               name: "topic 6"
          },{
               id:"1"
               name: "topic 7"
          },{
               id:"0"
               name: "topic 8"
          },
     ]
} ,
{
     owner: {
          signature: "",
          created: "2014-03-25 23:51:48",
          nickname: "",
          last_name: "Novel", 
          title: "",
          first_name: "Tim", 
          updated: "2019-10-21 21:26:24",
          email: "tim.novel@gmail.com"
     }
     ,
      topics: [ 
          {
               id:"0"
               name: "topic 16"
          },{
               id:"1"
               name: "topic 17"
          },{
               id:"0"
               name: "topic 18"
          },
     ]
 },
{    owner: {
          signature: "",
          created: "2014-03-25 23:51:48",
          nickname: "",
          last_name: "Kent", 
          title: "",
          first_name: "Bill", 
          updated: "2019-11-21 21:26:24",
          email: "bill.kent@gmail.com"
     },
     topics: [ 
          {
               id:"0"
               name: "topic 36"
          },{
               id:"1"
               name: "topic 37"
          },{
               id:"0"
               name: "topic 38"
          },
     ]
}  
]

当 API 收到关键字“ken”作为名称时,我需要发回前两个 JSON 对象和最后一个,其中包含主题值的组合详细信息(我的意思是 Bill Kent 的一个 JSON 对象和组合主题:6 ,7,8,36,37,38) 作为回应!

最佳答案

我必须先提一下,您的 JSON 字符串无效。因为所有键都必须用双引号括起来,并且属于同一 JSON 数组的所有 JSON 节点必须用逗号分隔。

以下代码片段显示了实现您想要的效果的另一种方法。首先使用Mapfirst_namelast_name& 连接作为键,然后组合 topics key 相同的 JSON 节点。最后转换Map到一个新的 JSON 节点。顺便说一句,Jackson (最流行的 JSON 库之一)被引入来演示这一点。

代码片段

 ObjectMapper mapper = new ObjectMapper();
 ArrayNode root = (ArrayNode) mapper.readTree(jsonStr);
 Map<String, JsonNode> rootMap = new HashMap<>();
 root.forEach(e -> {
     String firstName = e.get("owner").get("first_name").toString().toLowerCase();
     String lastName = e.get("owner").get("last_name").toString().toLowerCase();
     if (firstName.contains("ken") || lastName.contains("ken")) {
         String key = String.format("%s&%s", firstName, lastName);
         if (rootMap.containsKey(key)) {
             e.get("topics").forEach(e1 -> {
                 ((ArrayNode) rootMap.get(key).get("topics")).add(e1);
             });
         } else {
             rootMap.put(key, e);
         }
     }
 });

 ArrayNode rootNew = mapper.createArrayNode();
 rootMap.forEach((k,v) -> {
     rootNew.add(v);
 });
 System.out.println(rootNew.toString());

控制台输出

[ 
  { 
    "owner":{ 
      "signature":"",
      "created":"2014-03-25 23:51:48",
      "nickname":"",
      "last_name":"Kent",
      "title":"",
      "first_name":"Bill",
      "updated":"2019-11-21 21:26:24",
      "email":"bill.kent@gmail.com"
    },
    "topics":[ 
      { 
        "id":"0",
        "name":"topic 6"
      },
      { 
        "id":"1",
        "name":"topic 7"
      },
      { 
        "id":"0",
        "name":"topic 8"
      },
      { 
        "id":"0",
        "name":"topic 36"
      },
      { 
        "id":"1",
        "name":"topic 37"
      },
      { 
        "id":"0",
        "name":"topic 38"
      }
    ]
  },
  { 
    "owner":{ 
      "signature":"",
      "created":"2019-08-26 02:14:15",
      "nickname":"",
      "last_name":"Kennedy",
      "title":"null",
      "first_name":"Victor",
      "updated":"2019-11-24 20:58:57",
      "email":"v.kennedy@gmail.com"
    },
    "topics":[ 
      { 
        "id":"0",
        "name":"topic 1"
      },
      { 
        "id":"1",
        "name":"topic 2"
      },
      { 
        "id":"0",
        "name":"topic 3"
      }
    ]
  }
]
<小时/>

更新

给你!您可以使用 org.json 获得相同的结果如下:

JSONArray root = new JSONArray(jsonStr);
Map<String, JSONObject> rootMap = new HashMap<>();
for (int i = 0; i < root.length(); i++) {
    JSONObject obj = root.getJSONObject(i);
    String firstName = obj.getJSONObject("owner").getString("first_name").toLowerCase();
    String lastName = obj.getJSONObject("owner").getString("last_name").toLowerCase();
    if (firstName.contains("ken") || lastName.contains("ken")) {
        String key = String.format("%s&%s", firstName, lastName);
        if (rootMap.containsKey(key)) {
            obj.getJSONArray("topics").forEach(e1 -> {
                rootMap.get(key).getJSONArray("topics").put(e1);
            });
        } else {
            rootMap.put(key, obj);
        }
    }
}

JSONArray rootNew = new JSONArray();
rootMap.forEach((k,v) -> {
    rootNew.put(v);
});
System.out.println(rootNew.toString());

关于java - 使用 Lambda、Stream java 将值添加到两个嵌套的 JSON 数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59131175/

相关文章:

java - Gradle 5 和 Java 11 构建错误 : Why does Gradle think I'm using Java 10?

java - 有多个好的构造函数,Room 会选择无参数构造函数

java - 取消周转 worker 的问题

Javascript - 插入 JSON 数组

kotlin - 如何在Kotlin中从自身内部访问功能?

java - Bean 被初始化但注入(inject)抛出 npe

java - 如何使用java Spark进行获取请求

mysql - 日期格式发生奇怪的变化

java - 用 java8 lambda 函数替换所有

c# - 如何将 Expression<Func<T, DateTime>> 转换为 Expression<Func<T, object>>