首页 > 解决方案 > 在对象列表中获取 ActualDate 或 Previous date

问题描述

我有一个具有以下实现的类。

class Vehicle {
private Date date;
private int nbOfVehicleArriving;

   public Vehicle(Date date, int nbOfVehicleArriving) {
    this.date = date;
    this.nbOfVehicleArriving = nbOfVehicleArriving;
   }

   public int getNbOfVehicleArriving() {
    return nbOfVehicleArriving;
   }
}

我有这个对象的列表。我需要让日期等于或早于 dateTime 以显示 int 值

01/01/2018 00:00:00 12
01/01/2018 00:10:00 10
01/01/2018 01:00:00 5
01/01/2018 01:10:00 10

例子 :

01/01/2018 00:00:00 will give me 12
01/01/2018 00:01:00 will give me 12
01/01/2018 00:10:00 10 will give me 10
01/02/2018 01:10:00 10 (last value known : 10)

我知道我可以做一个 for 循环,但这是最好的方法吗?

谢谢

标签: javajava-stream

解决方案


我对您的Vehicle课程进行了一些修改,因为我认为任何人都不应该Date在 2018 年使用早已过时的课程:

public class Vehicle {
    public static final ZoneId TIME_ZONE = ZoneId.of("Europe/Nicosia");
    public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss");

    private Instant date;
    private int nbOfVehicleArriving;

    public Vehicle(String date, int nbOfVehicleArriving) {
        this.date = LocalDateTime.parse(date, FORMATTER).atZone(TIME_ZONE).toInstant();
        this.nbOfVehicleArriving = nbOfVehicleArriving;
    }

    // getters etc.
}

假设您的列表已排序

    Instant time = LocalDateTime.parse("01/01/2018 00:00:00", Vehicle.FORMATTER)
            .atZone(Vehicle.TIME_ZONE)
            .toInstant();
    OptionalInt number = myList.stream()
            .takeWhile(v -> !v.getDate().isAfter(time))
            .max(Comparator.comparing(Vehicle::getDate))
            .map(v -> OptionalInt.of(v.getNbOfVehicleArriving()))
            .orElseGet(OptionalInt::empty);

number在这种情况下,结果是OptionalInt[12]。其他结果:

  • 如果时间是 01/01/2018 00:01:00,结果仍然是OptionalInt[12].
  • 时间 01/01/2018 00:10:00 给出OptionalInt[10]
  • 时间 01/02/2018 01:10:00 也是如此。
  • 第一个列表元素之前的时间,例如 01/01/1979 00:00:00,给出OptionalInt.empty. 这是我想给出结果的一个原因OptionalInt(另一个是考虑到一个空列表)。

我不太清楚这是否比循环更好。你决定。

如果您的列表很长(例如一百万辆汽车)并且您遇到性能问题,您将需要使用二分搜索。流将完全不适合此。您可以在其他地方阅读有关二分搜索的信息。

如果您不能确定列表是否已排序,您只需要使用filter而不是takeWhile

    OptionalInt number = myList.stream()
            .filter(v -> !v.getDate().isAfter(time))
            .max(Comparator.comparing(Vehicle::getDate))
            .map(v -> OptionalInt.of(v.getNbOfVehicleArriving()))
            .orElseGet(OptionalInt::empty);

链接: Oracle 教程:日期时间解释如何使用java.time,我从哪里Instant上课。


推荐阅读