根据 ID 分组 JSON
Group JSON based on ID
我有一个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
将 id
和 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>>
) 的后续可变缩减将每个具有相同 Content.id
的 List<Content>
合并为一个具有平面映射 List<Tools>
的单个 Content
。具有这些修改的列表 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 个样本。
我有一个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
将 id
和 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>>
) 的后续可变缩减将每个具有相同 Content.id
的 List<Content>
合并为一个具有平面映射 List<Tools>
的单个 Content
。具有这些修改的列表 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 个样本。