如何使用流根据Map字段的条件过滤一组对象?

时间:2019-06-04 19:36:31

标签: java java-stream

我有一个ArrayList个对象中的一个Event,其中一个字段是Map<LocalDateTime, Auditorium> schedule-表示事件的时间表,即何时和在哪个礼堂播放。出于这个问题,Auditorium的实现并不重要。我想获取在某些日期/时间之间播放的事件的列表。我编写了一种方法,该方法可以查看每个事件的播出日期集,并仅过滤在给定时间范围内至少有一个播出日期的那些事件:

public List<Event> getForDateRange(LocalDateTime from, LocalDateTime to) {
    events.stream()
          .filter(s -> s.getSchedule()
              .keySet()
              .stream()
              .anyMatch(t -> t.compareTo(from) >= 0 && t.compareTo(to) <= 0))
          .collect(Collectors.toList());
}

然后我尝试如下测试该方法:

List<Event> events = new ArrayList<>();
Map<LocalDateTime, Auditorium> schedule = new HashMap<>();

schedule.put(LocalDateTime.of(2019, 4, 20, 18, 30), auditorium);
schedule.put(LocalDateTime.of(2019, 4, 20, 19, 30), auditorium);
schedule.put(LocalDateTime.of(2019, 4, 20, 20, 30), auditorium);
schedule.put(LocalDateTime.of(2019, 4, 20, 21, 30), auditorium);
Event event1 = new Event("Show1", schedule);
events.add(event1);
schedule.clear();

schedule.put(LocalDateTime.of(2019, 4, 20, 16, 30), auditorium);
schedule.put(LocalDateTime.of(2019, 4, 20, 17, 30), auditorium);
Event event2 = new Event("Show2", schedule);
events.add(event2);
schedule.clear();

LocalDateTime from = LocalDateTime.of(2000, 1, 1, 0, 0);
LocalDateTime to = LocalDateTime.of(2019, 4, 20, 20, 40);

List<Event> result = getForDateRange(from, to);

我希望result同时包含event1event2,但这是一个空列表。该方法的逻辑有什么问题?

谢谢。

1 个答案:

答案 0 :(得分:2)

除非您在创建活动时复制地图,否则活动时间表将为空。当您清除日程表时,您是从刚刚添加到事件列表的事件中清除日程表吗?因此,当您尝试比较事件时,事件列表中的两个时间表都是空的。

这是因为每个事件都包含对同一地图的相同引用,并且您将它们都清除了。

您需要为每个时间表声明一个新地图,并且不清除任何内容。