Java最早和最新的数据集合并并创建新的JSON对象

问题描述 投票:0回答:1

我有 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对象中。非常感谢任何帮助,提前致谢!

java json merge
1个回答
0
投票

我认为最好的选择是将

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"
  }
} ]
© www.soinside.com 2019 - 2024. All rights reserved.