在一个JSON对象中,一个字段具有相同的值,但其他字段具有不同的值,需要与项目列表中常见的其余值相同的值



我按资源名称分组项目列表,我得到的输出如下即在每个JSON对象resourceName是相同的,其他字段值是不同的,但我需要资源名称应该作为共同值和其他值作为值列表。


{"groupedResourceDtos": {
"Resource PopCheck": {
"9": [{
"id": 9,
"resourceName": "Resource PopCheck",
"groupedMonths": {
"id": 9,
"monthName": "Aug",
"noOfLicenses": 8
}
}],
"10": [{
"id": 10,
"resourceName": "Resource PopCheck",
"groupedMonths": {
"id": 10,
"monthName": "Sep",
"noOfLicenses": 11
}
}],
"11": [{
"id": 11,
"resourceName": "Resource PopCheck",
"groupedMonths": {
"id": 11,
"monthName": "Oct",
"noOfLicenses": 7
}
}]
}
}    

但我期待像

{"groupedResourceDtos": {
"resourceName":  "Resource PopCheck",
"groupedMonths": [{
"id": 9,
"monthName": "Aug",
"noOfLicenses": 8
},{
"id": 10,
"monthName": "Sep",
"noOfLicenses": 11
},{
"id": 11,
"monthName": "Oct",
"noOfLicenses": 7
}]
}}

请帮我解决这个问题

首先,需要为提到的JSON定义DTO类。可以这样做(使用Lombok注释):

@Data
static class Dto {
private Map<String, Map<String, List<MyResource>>> groupedResourceDtos;
}
@Data
static class MyResource {
int id;
String resourceName;
GroupedMonth groupedMonths;
}
@Data
static class GroupedMonth {
int id;
String monthName;
int noOfLicenses;
}

那么预期输出的DTO应该是这样的:

@Data
@AllArgsConstructor
static class Remap {
private String resourceName;
private List<GroupedMonth> groupedMonths;
}

假设有一个使用JacksonObjectMapper从输入JSON解析的Dto类的有效实例,则可以使用应用于映射内容的Stream::flatMapStream::map操作创建重新映射的实例:

String json = "{...};" // large input JSON 
ObjectMapper mapper = new ObjectMapper();
Dto dto = mapper.readValue(json, Dto.class);
Remap remap = dto.groupedResourceDtos.entrySet()
.stream()
.map(e -> new Remap(
e.getKey(), // resourceName
(e.getValue().values()      // Collection<List<MyResource>>
.stream()               // Stream<List<MyResource>>
.flatMap(List::stream)  // Stream<MyResource>
.map(MyResource::getGroupedMonths) // Stream<GroupedMonth>
.collect(Collectors.toList())
) // List<GroupedMonth>
))
.findFirst() // Optional<Remap>, dealing with only 1 value
.orElseThrow(IllegalArgumentException::new);

remap值可以序列化为JSON:

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(remap));

输出:

{
"resourceName" : "Resource PopCheck",
"groupedMonths" : [ {
"id" : 9,
"monthName" : "Aug",
"noOfLicenses" : 8
}, {
"id" : 10,
"monthName" : "Sep",
"noOfLicenses" : 11
}, {
"id" : 11,
"monthName" : "Oct",
"noOfLicenses" : 7
} ]
}

最新更新