使用groupingBy计算相邻列表元素之间的差异

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

我有一个已排序对象的列表

Round
,中间有一个字段
beginDate
。我想在流中使用
groupingBy
(或者其他更好的方法) 通过当前元素和列表中下一个元素的字段
differenceDaysNumber
的差来计算字段
beginDate
,除非列表中的下一个元素在字段中具有相同的值:并且较大的字段:
number 
,然后我们将这个值重写到所有副本中。

类似的东西,伪代码:

1 ob1 (differenceDaysNumber: ob1.beginDate-ob2.beginDate)
2 ob2 (differenceDaysNumber: ob3.beginDate-ob2.beginDate)
3 ob3 (differenceDaysNumber: ob4.beginDate-ob3.beginDate)
  3.1 ob3  (differenceDaysNumber: ob4.beginDate-ob3.beginDate) //this is copy with the same differenceDaysNumberas ob.3
  3.2 ob3 (differenceDaysNumber: ob4.beginDate-ob3.beginDate)  //this is copy with the same durTime as ob.3
4 ob4 (differenceDaysNumber: null)
@Builder
@Getter
public class Round {
    
    Integer number;
    LocalDateTime beginDate;
    @Setter
    Integer differenceDaysNumber;
}
var result = seriesInfoList.stream()
        .collect(Collectors.groupingBy(SeriesInfo::getStartTime));  //what next ?

//input
List<Round> input = List.of(
        new Round(1, LocalDateTime.of(2020, 12, 1, 12, 12, 12, 12), null),
        new Round(1, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), null),
        new Round(2, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), null),
        new Round(3, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), null),
        new Round(1, LocalDateTime.of(2020, 12, 17, 12, 12, 12, 12), null),
        new Round(1, LocalDateTime.of(2020, 12, 12, 12, 12, 12, 12), null));

//expected result
List<Round> output = List.of(
        new Round(1, LocalDateTime.of(2020, 12, 1, 12, 12, 12, 12), 10),
        new Round(1, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), 6),
        new Round(2, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), 6), //it is a copy because it has the same date and a larger number than the parent
        new Round(3, LocalDateTime.of(2020, 12, 11, 12, 12, 12, 12), 6), //it is a copy because it has the same date and a larger number than the parent
        new Round(3, LocalDateTime.of(2020, 12, 17, 12, 12, 12, 12), 5),
        new Round(1, LocalDateTime.of(2020, 12, 12, 12, 12, 12, 12), null));
java java-stream grouping
1个回答
0
投票
List<Round> output = input.stream()
    .collect(Collectors.groupingBy(Round::getBeginDate))
    .values()
    .stream()
    .flatMap(rounds -> {
        int maxNumber = rounds.stream().mapToInt(Round::getNumber).max().orElse(0);
        return rounds.stream().map(round -> {
            int differenceDays = 0;
            if (rounds.size() > 1 && round.getNumber() == maxNumber) {
                differenceDays = rounds.get(rounds.size() - 1).getBeginDate().getDayOfMonth()
                        - round.getBeginDate().getDayOfMonth();
            } else if (rounds.size() > 1) {
                differenceDays = rounds.get(rounds.indexOf(round) + 1).getBeginDate().getDayOfMonth()
                        - round.getBeginDate().getDayOfMonth();
            }
            round.setDifferenceDaysNumber(differenceDays);
            return round;
        });
    })
    .collect(Collectors.toList());

代码使用 groupingBy 对 Round 对象进行分组 开始日期。然后,它迭代分组值,计算 DifferenceDaysNumber 根据指定的条件,设置 每个 Round 对象的值。最后,它收集更新的回合 对象放入名为输出的新列表中。

生成的输出列表将包含 Round 对象,其 根据给定计算出的 DifferenceDaysNumber 字段 条件。

© www.soinside.com 2019 - 2024. All rights reserved.