I have modified your Vehicle
class a bit since I don’t think anyone should use the long outdated Date
class in 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.
}
Assuming your list is sorted
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);
The resulting number
in this case is OptionalInt[12]
. Other results:
- If the time is 01/01/2018 00:01:00, the result still is
OptionalInt[12]
.
- Time 01/01/2018 00:10:00 gives
OptionalInt[10]
.
- So does time 01/02/2018 01:10:00.
- A time before the first list element, for example 01/01/1979 00:00:00, gives
OptionalInt.empty
. This was one reason I wanted to give the result as an OptionalInt
(the other was to take an empty list into account).
It is not very clear to me whether this is better than a loop. You decide.
If your list is very long (for example a million vehicle counts) and you experience performance problems, you will want to use a binary search. A stream would be completely unsuited for this. You can read about binary search elsewhere.
If you cannot be sure that the list is sorted you just need to use filter
instead of 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);
Link: Oracle tutorial: Date Time explaining how to use java.time
, where I took the Instant
class from.