如何用Java 8 Stream过滤列表,保留同房间号的最新日期元素
Java 8 Stream 保留同一roomNumber下日期最新的对象
方法一:使用Collectors.toMap(推荐,一步到位)
这种方式无需先分组再处理,直接通过toMap的合并规则实现保留最新日期的对象,效率更高:
import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; // 假设TestClass的定义如下 class TestClass { private Long roomNumber; private LocalDate date; public TestClass(Long roomNumber, LocalDate date) { this.roomNumber = roomNumber; this.date = date; } public Long getRoomNumber() { return roomNumber; } public LocalDate getDate() { return date; } @Override public String toString() { return "TestClass(" + roomNumber + "L, LocalDate.of(" + date.getYear() + ", " + date.getMonthValue() + ", " + date.getDayOfMonth() + "))"; } } public class Main { public static void main(String[] args) { final List<TestClass> testClasses = Arrays.asList( new TestClass(100L, LocalDate.of(2020, 1, 10)), new TestClass(100L, LocalDate.of(2019, 1, 10)), new TestClass(101L, LocalDate.of(2020, 7, 20)), new TestClass(102L, LocalDate.of(2020, 1, 9)), new TestClass(103L, LocalDate.of(2020, 1, 11)), new TestClass(104L, LocalDate.of(2020, 2, 13)) ); List<TestClass> filteredList = testClasses.stream() .collect(Collectors.toMap( TestClass::getRoomNumber, // 以roomNumber作为Map的key Function.identity(), // 以TestClass对象本身作为value // 当key重复时,保留日期更晚的对象 (existing, newObj) -> existing.getDate().isAfter(newObj.getDate()) ? existing : newObj )) .values() // 获取所有保留的对象 .stream() .collect(Collectors.toList()); // 打印结果 System.out.println(filteredList); } }
方法二:基于你已有的groupingBy继续处理
如果坚持用分组的方式,可以对每个分组的列表筛选出日期最新的元素:
import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // TestClass定义同上 public class Main { public static void main(String[] args) { final List<TestClass> testClasses = Arrays.asList( new TestClass(100L, LocalDate.of(2020, 1, 10)), new TestClass(100L, LocalDate.of(2019, 1, 10)), new TestClass(101L, LocalDate.of(2020, 7, 20)), new TestClass(102L, LocalDate.of(2020, 1, 9)), new TestClass(103L, LocalDate.of(2020, 1, 11)), new TestClass(104L, LocalDate.of(2020, 2, 13)) ); Map<Long, List<TestClass>> grouped = testClasses.stream() .collect(Collectors.groupingBy(TestClass::getRoomNumber)); List<TestClass> filteredList = grouped.values().stream() // 对每个分组的列表,找出日期最大的元素 .map(group -> group.stream() .max(Comparator.comparing(TestClass::getDate)) .orElse(null) // 分组后的列表至少有一个元素,此分支不会触发 ) .collect(Collectors.toList()); // 打印结果 System.out.println(filteredList); } }
输出结果
两种方法最终都会得到你期望的过滤后列表:
[ TestClass(100L, LocalDate.of(2020, 1, 10)), TestClass(101L, LocalDate.of(2020, 7, 20)), TestClass(102L, LocalDate.of(2020, 1, 9)), TestClass(103L, LocalDate.of(2020, 1, 11)), TestClass(104L, LocalDate.of(2020, 2, 13)) ]
内容的提问来源于stack exchange,提问作者thottivelli
相关产品推荐
相关产品推荐

