如何基于自定义规则过滤Java列表,分组后保留日期字段最小的对象
实现方案
Java 8及以上版本直接用Stream API即可实现,无需引入第三方依赖,核心逻辑是按指定字段分组后每组取日期最小的实例。
前置准备
首先确保自定义类A提供对应字段的Getter方法、全参构造器:
import java.time.LocalDate; class A { String field1; String field2; String field3; LocalDate dateField; // 全参构造器 public A(String field1, String field2, String field3, LocalDate dateField) { this.field1 = field1; this.field2 = field2; this.field3 = field3; this.dateField = dateField; } // Getter方法 public String getField1() { return field1; } public String getField2() { return field2; } public String getField3() { return field3; } public LocalDate getDateField() { return dateField; } }
核心实现代码
import java.util.*; import java.util.stream.Collectors; import java.time.LocalDate; public class GroupFilterDemo { public static void main(String[] args) { // 构造示例数据 List<A> originList = Arrays.asList( new A("field1","field2","field3",null), new A("field1","field2","field3",LocalDate.now()), new A("field1","field2","field3",LocalDate.now().plusMonths(3)), new A("4","5","6",LocalDate.now().plusMonths(3)), new A("7","8","9",LocalDate.now().plusMonths(3)) ); List<A> result = getMinDatePerGroup(originList); // 验证结果 result.forEach(item -> System.out.printf("field1=%s, field2=%s, field3=%s, date=%s%n", item.getField1(), item.getField2(), item.getField3(), item.getDateField())); } public static List<A> getMinDatePerGroup(List<A> originList) { return originList.stream() // 按field1、field2、field3三个字段分组 .collect(Collectors.groupingBy( item -> Arrays.asList(item.getField1(), item.getField2(), item.getField3()), // 每组保留dateField最小的实例,null日期视为比所有有效日期大 Collectors.minBy(Comparator.comparing(A::getDateField, Comparator.nullsLast(LocalDate::compareTo))) )) .values() .stream() .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); } }
逻辑说明
- 分组key直接用
Arrays.asList拼接三个字段,无需额外自定义key类或者重写A类的equals、hashCode方法,因为List的equals/hashCode逻辑本身就会按元素值对比,完全符合分组规则。 - 日期排序用
Comparator.nullsLast控制null值的优先级:示例需求中null日期需要被排除,所以把null设为比所有有效日期大,minBy就会自动取最小的有效日期;如果后续需要把null当成最小优先级,替换成Comparator.nullsFirst即可。 - 如果使用Java 8以下版本,也可以手动用HashMap实现:遍历所有元素,以三个字段组合为key存入Map,遇到同key元素时对比日期,只保留更小的那个即可。
内容的提问来源于stack exchange,提问作者2dor
相关产品推荐
相关产品推荐

