我有 2 个查询,它们为最早和最新的数据集返回相同的对象。
例如:
earliestDataset = [
{'id' : 123, 'highlights': 2, 'created_date': 2024-01-01, 'saves':5, 'wins':3},
{'id' : 124, 'highlights': 3, 'created_date': 2024-01-03, 'saves':2, 'wins':1},
{'id' : 253, 'highlights': 5, 'created_date': 2024-02-02, 'saves':3, 'wins':7}]
latestDataset = [
{'id' : 123, 'highlights': 6, 'created_date': 2024-04-01, 'saves':22, 'wins':14},
{'id' : 124, 'highlights': 9, 'created_date': 2024-04-03, 'saves':8, 'wins':9},
{'id' : 253, 'highlights': 12, 'created_date': 2024-03-02, 'saves':15, 'wins':20}]
我想合并数据集并以新的 json 格式返回,例如:
{
"id": "123",
"highlights": [
{
"earliest": "2",
"latest": "6",
"difference": "+4"
}
],
"created_date": [
{
"earliest": "2024-01-01",
"latest": "2024-04-01"
}
],
"saves": [
{
"earliest": "5",
"latest": "22",
"difference": "+17"
}
],
"wins": [
{
"earliest": "7",
"latest": "20",
"difference": "+13"
}
]
}
我不知道是否应该使用map或stream来比较两个列表,找到id并将值映射到新的Json对象中。非常感谢任何帮助,提前致谢!
我认为最好的选择是将
Map
与Jackson
一起使用。
public class Foo {
@Data
public static final class Event {
private int id;
private int highlights;
@JsonProperty("created_date")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date createdDate;
private int saves;
private int wins;
}
@Data
@Builder
public static final class MergeEvent {
private int id;
private Range highlights;
@JsonProperty("created_date")
private Range createdDate;
private Range saves;
private Range wins;
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static final class Range {
private String earliest;
private String latest;
private String difference;
}
}
public static void main(String... args) throws JsonProcessingException {
String jsonEarlies = "[\n" +
" {\n" +
" \"id\":123,\n" +
" \"highlights\":2,\n" +
" \"created_date\":\"2024-01-01\",\n" +
" \"saves\":5,\n" +
" \"wins\":3\n" +
" },\n" +
" {\n" +
" \"id\":124,\n" +
" \"highlights\":3,\n" +
" \"created_date\":\"2024-01-03\",\n" +
" \"saves\":2,\n" +
" \"wins\":1\n" +
" },\n" +
" {\n" +
" \"id\":253,\n" +
" \"highlights\":5,\n" +
" \"created_date\":\"2024-02-02\",\n" +
" \"saves\":3,\n" +
" \"wins\":7\n" +
" }\n" +
"]";
String jsonLatest = "[\n" +
" {\n" +
" \"id\":123,\n" +
" \"highlights\":6,\n" +
" \"created_date\":\"2024-04-01\",\n" +
" \"saves\":22,\n" +
" \"wins\":14\n" +
" },\n" +
" {\n" +
" \"id\":124,\n" +
" \"highlights\":9,\n" +
" \"created_date\":\"2024-04-03\",\n" +
" \"saves\":8,\n" +
" \"wins\":9\n" +
" },\n" +
" {\n" +
" \"id\":253,\n" +
" \"highlights\":12,\n" +
" \"created_date\":\"2024-03-02\",\n" +
" \"saves\":15,\n" +
" \"wins\":20\n" +
" }\n" +
"]";
String json = merge(jsonEarlies, jsonLatest);
System.out.println(json);
}
public static String merge(String jsonEarliest, String jsonLatest) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Map<Integer, Event> earliest = readEventsAndGroupById(objectMapper, jsonEarliest);
Map<Integer, Event> latest = readEventsAndGroupById(objectMapper, jsonLatest);
List<MergeEvent> mergeEvents = merge(earliest, latest);
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(mergeEvents);
}
private static Map<Integer, Event> readEventsAndGroupById(ObjectMapper mapper,
String json) throws JsonProcessingException {
List<Event> events = mapper.readValue(json, new TypeReference<>() {
});
return events.stream().collect(Collectors.toMap(Event::getId, Function.identity()));
}
private static List<MergeEvent> merge(Map<Integer, Event> earliest,
Map<Integer, Event> latest) {
return Stream.concat(earliest.keySet().stream(), latest.keySet().stream())
.distinct()
.map(id -> merge(id, earliest.get(id), latest.get(id)))
.sorted(Comparator.comparingInt(MergeEvent::getId))
.collect(Collectors.toList());
}
private static MergeEvent merge(int id, Event earliest, Event latest) {
return MergeEvent.builder()
.id(id)
.highlights(calcRange(earliest.getHighlights(), latest.getHighlights()))
.createdDate(calcRange(earliest.getCreatedDate(), latest.getCreatedDate()))
.saves(calcRange(earliest.getSaves(), latest.getSaves()))
.wins(calcRange(earliest.getWins(), latest.getWins()))
.build();
}
private static MergeEvent.Range calcRange(int earliest, int latest) {
return MergeEvent.Range.builder()
.earliest(String.valueOf(earliest))
.latest(String.valueOf(latest))
.difference(earliest == latest ? null : String.format("%+d", latest - earliest))
.build();
}
private static MergeEvent.Range calcRange(Date earliest, Date latest) {
return MergeEvent.Range.builder()
.earliest(String.format("%1$tY-%1$tm-%1$td", earliest))
.latest(String.format("%1$tY-%1$tm-%1$td", latest))
.build();
}
}
输出:
[ {
"id" : 123,
"highlights" : {
"earliest" : "2",
"latest" : "6",
"difference" : "+4"
},
"saves" : {
"earliest" : "5",
"latest" : "22",
"difference" : "+17"
},
"wins" : {
"earliest" : "3",
"latest" : "14",
"difference" : "+11"
},
"created_date" : {
"earliest" : "2024-01-01",
"latest" : "2024-04-01"
}
}, {
"id" : 124,
"highlights" : {
"earliest" : "3",
"latest" : "9",
"difference" : "+6"
},
"saves" : {
"earliest" : "2",
"latest" : "8",
"difference" : "+6"
},
"wins" : {
"earliest" : "1",
"latest" : "9",
"difference" : "+8"
},
"created_date" : {
"earliest" : "2024-01-03",
"latest" : "2024-04-03"
}
}, {
"id" : 253,
"highlights" : {
"earliest" : "5",
"latest" : "12",
"difference" : "+7"
},
"saves" : {
"earliest" : "3",
"latest" : "15",
"difference" : "+12"
},
"wins" : {
"earliest" : "7",
"latest" : "20",
"difference" : "+13"
},
"created_date" : {
"earliest" : "2024-02-02",
"latest" : "2024-03-02"
}
} ]