java - 根据 ID 分组 JSON
问题描述
我有一个json
{
"content": [
{
"idnumber": "666",
"name": "mark",
"type": "band",
"tools": [
{
"idtools": "5657",
"blabla": null,
"blabla": false,
}
]
},
{
"idnumber": "666",
"name": "mark",
"type": "band",
"tools": [
{
"idtools": "5658",
"blabla": null,
"blabla": false
}
]
}
]
}
在内容数组中,我有 2 个 json。我想将我的 json 更改为此,因为它们具有相同的 ID 号。
{
"content": [
{
"idnumber": "666",
"name": "mark",
"type": "band",
"tools": [
{
"idtools": "5657",
"blabla": null,
"blabla": false,
},
{
"idtools": "5658",
"blabla": null,
"blabla": false
}
]
}
]
}
如何使用 distinct 或 filter 做到这一点?
我试图区分它并映射它,但仍然有错误。
解决方案
假设以下对象与您的 JSON 结构匹配(为简洁起见,我使用 Lombok):
@Data
@AllArgsConstructor
@NoArgsConstructor
class Content {
int idNumber;
String name;
String type;
List<Tool> tools;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Tool {
int idTools;
String blabla;
}
您可以将 Stream API 与groupingBy
byid
和reduce
值合二为一。
List<Content> mergedContents = contents.stream()
.collect(Collectors.groupingBy(Content::getIdNumber))
.values()
.stream()
.reduce(
new ArrayList<>(), // mutable List
(left, right) -> {
Content content = right.get(0); // they are same (by id)
List<Tool> tools = right.stream() // from each new list
.flatMap(c -> c.getTools().stream()) // .. flatmap the tools
.collect(Collectors.toList()); // .. and extract to a list
content.setTools(tools); // set the List<Tool>
left.add(content); // add the Content
return left; // return the left list
},
(left, right) -> left); // only for parallel Stream
Collectors.groupingBy(Content::getIdNumber)
产生的结构来自Map<Integer, List<Content>>
. 随后对映射值的可变归约 ( Collection<List<Content>>
) 将每个 with same 合并List<Content>
为Content.id
一个Content
with flatmapped List<Tools>
。Content
作为归约的结果,返回带有这些修改的列表。
样本数据
List<Content> contents = new ArrayList<>();
contents.add(new Content(666, "Mark", "Band",
Collections.singletonList(new Tool(5657, null))));
contents.add(new Content(666, "Mark", "Band",
Collections.singletonList(new Tool(5658, null))));
List<Content> mergedContents = /* solution */
mergedContents.forEach(System.out::println);
Main.Content(idNumber=666, name=Mark, type=Band, tools=[Main.Tool(idTools=5657, blabla=null), Main.Tool(idTools=5658, blabla=null)])
这等于您的 JSON 样本。
推荐阅读
- bash - gunzip file1.gz file2.gz 比遍历文件和对每个文件进行gunziping更快吗
- php - 如何在php中为SQL查询添加标题和边框
- java - 应拆箱“字符串”原始类型,但返回 null
- html - 嵌套表格 - 单元格的宽度不正确
- python-3.x - 在 buildroot 映像中添加 python_opencv
- javascript - 如何使用 Ionic PWA Starter Kit 创建自定义 Stencil 组件
- angular - TypeError: readFile$(...).mergeMap 不是 firebase 服务函数中的函数
- android - Handler Thread:每个线程只能创建一个 Looper
- java - 如何编辑文件中的行
- wordpress - 迁移 Wordpress 站点时 Apache2 失败