You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于自定义规则过滤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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:27:03