根据 LocalDateTime 对象列表和使用流获取的时隙列表创建可用时隙列表

Dmy*_*pov 5 java list java-stream localdatetime

我有一个包含具有以下字段的List<Timeslot>实体:Timeslot

  1. timeslot_id;
  2. day;
  3. start_time;
  4. end_time

例如,此列表包含两条记录:

  • start_time第一个记录的等于9:00end_time等于10:00

  • start_time第二个对象的 equals10:00end_timeequals 11:00

第二个列表包含时间戳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]
Run Code Online (Sandbox Code Playgroud)

我需要创建第三个List<Timeslot>,其中包含Timeslot第一个列表中除这两个之外的 s 。

在这种情况下,结果第三个列表应该包含六个Timeslot类对象。

start_timefirst 应该等于2022-04-16T08:00end_time 2022-04-16T09:00。即每隔一个时间段start_time和之间的差异是一小时end_time

因此,从上面提供的时间戳列表构造的结果应包含六个对象:

  • start_time伊斯兰8:00国。end_time9:00
  • start_time伊斯兰11:00国。end_time12:00
  • start_time12:00end_time13:00……等等。

I 的对象start_time 9:0010:00不会出现在第三个列表中,因为它们已经被预订(出现在第一个列表中)。

我尝试使用 Java Streams创建第三个列表,它应该比较第二个列表start_time中的字段和end_time时间戳。

我已经尝试过,但结果列表始终为空:

List<Timeslot> availableSlots = query.stream()
    .filter(timeslot -> timestamps.contains(timeslot.getStartTime()))
    .toList();
Run Code Online (Sandbox Code Playgroud)

时段类别:

@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;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*nko 6

我已经Timeslot针对此问题简化了您的类(出于演示目的),因为对于此任务,您主要关注每个时间段的开始时间结束时间

我的方法是通过从已占用的每个时间段LocalDateTime(由第一个列表表示)中提取开始时间来创建一组对象。

然后query在列表上创建一个流并过滤集合中不存在的日期时间对象。然后使用每个日期时间对象作为开始时间创建一个时间段(结束时间=开始时间+ 1 小时)。并将所有流元素收集到一个列表中。

注意:终端操作toList()创建一个不可变列表,您可以通过应用来获取可变列表collect(Collectors.toList())

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);
}
Run Code Online (Sandbox Code Playgroud)

简化的虚拟Timeslot

public class Timeslot {
    private LocalDateTime startTime;
    private LocalDateTime endTime;
    
    // constructor, getters, toString()
}
Run Code Online (Sandbox Code Playgroud)

输出

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}
Run Code Online (Sandbox Code Playgroud)