Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取对象列表中的实际日期或上一个日期_Java_Java Stream - Fatal编程技术网

Java 获取对象列表中的实际日期或上一个日期

Java 获取对象列表中的实际日期或上一个日期,java,java-stream,Java,Java Stream,我有一个具有以下实现的类 class Vehicle { private Date date; private int nbOfVehicleArriving; public Vehicle(Date date, int nbOfVehicleArriving) { this.date = date; this.nbOfVehicleArriving = nbOfVehicleArriving; } public int getNbOfVehicleArri

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

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 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循环,但这是最好的方法吗


谢谢

我对您的
车辆
等级做了一些修改,因为我不认为任何人应该在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);
在这种情况下,生成的
编号
optionant[12]
。其他结果:

  • 如果时间是2018年1月1日00:01:00,结果仍然是
    OptionalInt[12]
  • 时间2018年1月1日00:10:00给出了选项[10]
  • 时间2018年2月1日01:10:00也是如此
  • 第一个列表元素之前的时间,例如01/01/1979 00:00:00,给出了
    optionant.empty
    。这是我希望将结果作为一个
    选项给出的原因之一(另一个原因是考虑到一个空列表)
我不太清楚这是否比循环好。由你决定

如果您的列表很长(例如一百万辆车),并且您遇到性能问题,您将需要使用二进制搜索。一条小溪完全不适合这样做。你可以在别处阅读有关二进制搜索的内容

如果无法确定列表是否已排序,只需使用
过滤器
,而不是
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);

链接:解释如何使用
java.time
,我在那里学习了
Instant
课程。

无论如何,你必须迭代车辆集合。如果有大量对象,请考虑使用某种数据库。由于使用了标记,那里的过滤速度会更快。请为我们提供
for loop
,以演示您的目标。这个解释还不清楚。重复:因为您标记了java流:您可以使用流。筛选实际日期之前的日期或实际日期,然后取最大日期。是否更好可能是口味的问题。但是,
Date
类早已过时,您可能更喜欢使用
Instant
或来自的其他类。
    OptionalInt number = myList.stream()
            .filter(v -> !v.getDate().isAfter(time))
            .max(Comparator.comparing(Vehicle::getDate))
            .map(v -> OptionalInt.of(v.getNbOfVehicleArriving()))
            .orElseGet(OptionalInt::empty);