Skip to content
java
@Getter
@Setter
public class Data {
    private String date;
    private String id;
    private String report;
    private Double sum;
    private Double avg;
}
java
@ToString
@Getter
@Setter
@JsonNaming(value = PropertyNamingStrategies.UpperSnakeCaseStrategy.class)
@SuppressWarnings({"squid:S116"})
public class PivotData {
    @JsonProperty("date")
    private String date;
    @JsonProperty("id")
    private String id;
    private Double POWER;
    private Double ENERGY;
    private Double TEMP;
    private Double HERTZ;
}
java
@UtilityClass
public class PivotDataConverter {
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final Map<String, String> AVG_REPORTS = Set.of("POWER", "TEMP", "HERTZ").stream()
            .collect(Collectors.toUnmodifiableMap(s -> s, s -> s));

    public static List<PivotData> from(List<Data> list) {
        return MAPPER.convertValue(list.stream()
                .collect(Collectors.groupingByConcurrent(data -> Pair.of(data.getDate(), data.getId())))
                .entrySet()
                .parallelStream()
                .map(entry -> {
                    Map<String, Object> row = entry.getValue()
                            .stream()
                            .collect(Collectors.toMap(Data::getReport,
                                    data -> AVG_REPORTS.containsKey(data.getReport()) ? data.getAvg() : data.getSum()));
                    row.put("date", entry.getKey().getLeft());
                    row.put("id", entry.getKey().getRight());
                    return row;
                }).toList(), new TypeReference<>() {
        });
    }
}

날짜와 리포트 항목으로 이루어진 시계열 데이터의 통계 정보를 날짜와 리포트 항목별 값 형태로 이루어지는 피봇 테이블 리스트로 바꿔보았습니다. 날짜를 포함한 하나 이상의 필드로 그룹핑 되면서 리포트 항목에 따라 합계 또는 평균값을 사용해야 합니다. Collectors.groupingBy 를 사용해서 데이터 리스트를 날짜 기준으로 그룹핑하고 각 리포트 항목을 하나의 Map 으로 생성하고나서 ObjectMapper를 사용해 피봇된 형태의 클래스를 가진 리스트로 변환했습니다. 위 예시에서 전력량에 대해서만 합계를 사용하지만 실제로는 대부분의 리포트 항목에 대해 합계값을 사용하게 되므로 평균값을 사용해야하는 리포트 항목만을 별도로 관리하도록 코드를 작성했습니다.

Released under the MIT License.