I have a List<Timeslot>
that contains entity Timeslot
with the following fields:
timeslot_id
;day
;start_time
;end_time
.
For example, this list contains two records:
start_time
of the first record equals9:00
andend_time
equals10:00
.start_time
of second object equals10:00
andend_time
equals11:00
.
And the second list contains timestamps List<LocalDateTime>
:
[2022-04-16T08:00, 2022-04-16T09:00, 2022-04-16T10:00, 2022-04-16T11:00, 2022-04-16T12:00, 2022-04-16T13:00, 2022-04-16T14:00, 2022-04-16T15:00]
I need to create a third List<Timeslot>
that will contain Timeslot
s except this two from the first list.
In this case, as a result, the third list should contain six objects of Timeslot
class.
start_time
of first should equal 2022-04-16T08:00
and end_time 2022-04-16T09:00
. I.e. the difference between start_time
and end_time
for every other timeslot is one hour.
So, the result constructed from the list of timestamps provided above should contain six objects:
start_time
is8:00
,end_time
is9:00
.start_time
is11:00
,end_time
is12:00
.start_time
is12:00
,end_time
is13:00
… and so on.
I the objects for with start_time
9:00
and 10:00
will not be present in the third list because they are booked already (present in the first list).
I tried to create the third list using Java Streams, which should compare fields start_time
and end_time
with timestamps from the second list.
I’ve tried this, but the resulting list is always empty:
List<Timeslot> availableSlots = query.stream() .filter(timeslot -> timestamps.contains(timeslot.getStartTime())) .toList();
Timeslot class:
@Entity(name = "timeslot") public class Timeslot { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "timeslot_id") private Integer id; @Column(name = "day", columnDefinition = "DATE") private LocalDateTime day; @Column(name = "start_time") private LocalDateTime startTime; @Column(name = "end_time") private LocalDateTime endTime; @Column(name = "user_id") private Integer userId; @Column(name = "is_recorded") private Boolean isRecorded; }
Advertisement
Answer
I’ve simplified your Timeslot
class for this problem (for demonstration purposes) since for this task you primarily concern about the start time and end time of each timeslot.
My approach is to create a set of LocalDateTime
objects by extracting the start time from each timeslot that is already taken (represented by your first list).
Then create a stream over the query
list and filter the date-time object that are not present in the set. Then create a timeslot using each date-time object as a start time (end time = start time + 1 hour). And collect all the stream elements into a list.
Note: terminal operation toList()
creates an immutable list, you can obtain a mutable list by applying collect(Collectors.toList())
instead.
public static void main(String[] args) { List<LocalDateTime> query = List.of(LocalDateTime.of(2022, 04, 16, 8, 00), LocalDateTime.of(2022, 04, 16, 9, 00), LocalDateTime.of(2022, 04, 16, 10, 00), LocalDateTime.of(2022, 04, 16, 11, 00), LocalDateTime.of(2022, 04, 16, 12, 00), LocalDateTime.of(2022, 04, 16, 13, 00), LocalDateTime.of(2022, 04, 16, 14, 00), LocalDateTime.of(2022, 04, 16, 15, 00)); List<Timeslot> timeslots = // timeslots that already taken List.of(new Timeslot(LocalDateTime.of(2022, 04, 16, 9, 00), LocalDateTime.of(2022, 04, 16, 10, 00)), new Timeslot(LocalDateTime.of(2022, 04, 16, 10, 00), LocalDateTime.of(2022, 04, 16, 11, 00))); Set<LocalDateTime> takenStartTime = timeslots.stream() .map(Timeslot::getStartTime) .collect(Collectors.toSet()); List<Timeslot> availableSlots = query.stream() .filter(dateTime -> !takenStartTime.contains(dateTime)) .map(dateTime -> new Timeslot(dateTime, dateTime.plusHours(1))) .toList(); availableSlots.forEach(System.out::println); }
Simplified dummy Timeslot
class
public class Timeslot { private LocalDateTime startTime; private LocalDateTime endTime; // constructor, getters, toString() }
Output
Timeslot{start_time=2022-04-16T08:00, end_time=2022-04-16T09:00} Timeslot{start_time=2022-04-16T11:00, end_time=2022-04-16T12:00} Timeslot{start_time=2022-04-16T12:00, end_time=2022-04-16T13:00} Timeslot{start_time=2022-04-16T13:00, end_time=2022-04-16T14:00} Timeslot{start_time=2022-04-16T14:00, end_time=2022-04-16T15:00} Timeslot{start_time=2022-04-16T15:00, end_time=2022-04-16T16:00}