Java 8 Stream实现双列表遍历与日期范围过滤问题
用Java 8 Stream筛选list2中处于list1日期范围内的记录
前提假设
假设两个列表中的元素都是包含日期字段的自定义对象(比如Record类,包含LocalDate date属性),我们需要先从list1中提取出日期范围的上下限(即list1所有日期的最小值和最大值),再筛选list2中日期落在该范围内的记录。
代码实现
首先定义示例实体类:
import java.time.LocalDate; class Record { private LocalDate date; public Record(LocalDate date) { this.date = date; } public LocalDate getDate() { return date; } @Override public String toString() { return "Record{" + "date=" + date + '}'; } }
然后是核心逻辑:
import java.time.LocalDate; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; public class DateRangeFilter { public static void main(String[] args) { List<Record> list1 = List.of( new Record(LocalDate.of(2024, 1, 10)), new Record(LocalDate.of(2024, 1, 20)) ); List<Record> list2 = List.of( new Record(LocalDate.of(2024, 1, 5)), new Record(LocalDate.of(2024, 1, 15)), new Record(LocalDate.of(2024, 1, 25)) ); // 从list1提取日期范围的最小和最大值,处理空列表情况 Optional<LocalDate> minDateOpt = list1.stream() .map(Record::getDate) .min(LocalDate::compareTo); Optional<LocalDate> maxDateOpt = list1.stream() .map(Record::getDate) .max(LocalDate::compareTo); // 仅当list1非空时执行筛选 if (minDateOpt.isPresent() && maxDateOpt.isPresent()) { LocalDate minDate = minDateOpt.get(); LocalDate maxDate = maxDateOpt.get(); List<Record> filteredList = list2.stream() .filter(record -> { LocalDate date = record.getDate(); // 处理日期为null的情况,避免空指针 return date != null && !date.isBefore(minDate) && !date.isAfter(maxDate); }) .collect(Collectors.toList()); System.out.println("筛选后的记录:"); filteredList.forEach(System.out::println); } else { System.out.println("list1为空,无法确定日期范围"); } } }
关键说明
- 日期范围提取:通过
Stream.min()和Stream.max()获取list1的日期边界,用Optional处理list1为空的情况,避免抛出NoSuchElementException。 - 空值处理:过滤时判断
date是否为null,防止空指针异常。 - 区间判断:用
!date.isBefore(minDate)和!date.isAfter(maxDate)实现闭区间(包含起止日期)的判断,若需要开区间可调整为date.isAfter(minDate) && date.isBefore(maxDate)。
扩展场景:list1包含多个独立日期区间
如果list1是多个日期区间(比如每个元素是包含startDate和endDate的DateRange对象),筛选逻辑可调整为:
class DateRange { private LocalDate start; private LocalDate end; // 构造器、getter方法省略 public LocalDate getStart() { return start; } public LocalDate getEnd() { return end; } } // 筛选逻辑 List<Record> filteredList = list2.stream() .filter(record -> { LocalDate date = record.getDate(); if (date == null) return false; // 判断日期是否落在任意一个区间内 return list1.stream() .anyMatch(range -> !date.isBefore(range.getStart()) && !date.isAfter(range.getEnd())); }) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Richa
相关产品推荐
相关产品推荐

