从日期列表中获取距离指定日期最近的日期?

3

我在Temp类中有两个日期字段,分别是validFromDate和asOfDate。我手头有一个List。我需要将其中validFromDate最接近asOfDate的记录的标志(flag)设为true。

例如:

List<temp> {
    Temp1:
        asOfDate: 2018-01-04
        validFrom: 2018-01-01
    Temp2:
        asOfDate: 2018-01-04
        validFrom: 2018-01-02
    Temp3:
        asOfDate: 2018-01-04
        validFrom: 2018-01-03
}

输出应为Temp3,因为此validFrom最接近asOfdate。我将为此Temp2设置标志为true。

如何使用Java 8流实现此目标?


最后一个应该是 Temp3 吗? - Eugene
2
你尝试过任何代码吗? - Tim Biegeleisen
私有限制 getClosestApplicableLimit(List<Limit> limitList, LocalDate asOfDate) { LocalDate currentNearestDate = null; for (Limit limit : limitList) { if (limit.getValidFrom().isBefore(asOfDate) && (currentNearestDate == null || limit.getValidFrom().isAfter(currentNearestDate))) { currentNearestDate = limit.getValidFrom(); applicableLimit = limit; } } 返回适用的限制; } - Sahil
我尝试了上面的代码。但是想知道如何在Java流中实现。 - Sahil
3个回答

3
  temp.stream()
      .map(x -> new SimpleEntry<>(x, ChronoUnit.DAYS.between(x.getAsOfDate(), x.getValidFrom())))
      .min(Comparator.comparingLong(Entry::getValue))
      .map(Entry::getKey)
      .orElse(...);

或者更简单:
test.stream()
    .min(Comparator.comparingLong(x -> ChronoUnit.DAYS.between(x.asOfDate , x.validFrom)));

@Sahil 这个列表会包含什么? - Eugene
我不想对列表进行排序。我想找到最接近asOfDate的validFrom日期,并将该记录的标志更新为true或false,然后返回更新后的列表。 - Sahil
最接近asOfDate的记录。所有记录的asOfDate相同。我只想找到最接近asOfDate的validFromdate记录,并将其适用标志更新为false。其余记录的适用标志应设置为false。 - Sahil
1
@Sahil 在这种情况下,您需要先进行排序,然后再更新标志:List<Test> result = test.stream() .sorted(Comparator.comparingLong(x -> ChronoUnit.DAYS.between(x.asOfDate, x.validFrom))) .collect(Collectors.toList()); Spliterator<Test> sp = result.stream().spliterator(); sp.tryAdvance(x -> x.setWhatEverFlag(true)); sp.forEachRemaining(x -> x.setWhatEverFlar(false)); - Eugene
@Sahil 不要!从这里开始自己编写代码。 - Eugene
显示剩余8条评论

1

您可以使用ChronoUnit.DAYS.between来计算日期之间的天数,然后使用Stream.min来获取最小值:

Optional<MyClass> shortestDate = myList.stream()
    .min(
        Comparator.comparingLong(
            item -> ChronoUnit.DAYS.between(item.asOfDate(), item.validFrom())
        )
    );

0
我们可以尝试根据asOfDatevalidFrom日期之间的绝对差来排序您的列表,然后从排序后的列表中取第一个元素。代码如下:
list.sort((Temp t1, Temp t2)
    ->Long.compare(Math.abs(t1.getAsOfDate().getTime() - t1.getValidFrom().getTime()),
        Math.abs(t2.getAsOfDate().getTime() - t2.getValidFrom().getTime())));
System.out.println(list.get(0));

假设您的日期是旧的Java 8之前的java.util.Date类。如果不是,我的代码将需要更改。这还假定您可以接受更改列表的顺序。

请参考下面的演示链接,它展示了上述lambda排序实际上适用于一小组样本数据。

演示

编辑:

如果您不想更改原始列表,而是想更新单个匹配的Temp元素,则可以复制列表,然后对副本进行排序:

List<Temp> copy = new ArrayList<>(list);
// sort copy, per above
// then update the original list
Temp match = copy.get(0);
int index = list.indexOf(match);
list.get(index).setFlag(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接