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

如何用Java 8 Stream筛选各ID对应最高版本的对象?

Java 8 Stream实现按ID筛选最高版本对象

首先需要补充MyObj类的必要方法(原代码缺少构造方法、属性访问器,这是Stream操作的基础):

public class MyObj {
    private String ID;
    private String version;

    // 构造方法
    public MyObj(String ID, String version) {
        this.ID = ID;
        this.version = version;
    }

    // Getter方法
    public String getID() {
        return ID;
    }

    public String getVersion() {
        return version;
    }

    // 可选:重写toString方便调试
    @Override
    public String toString() {
        return "MyObj{" +
                "ID='" + ID + '\'' +
                ", version='" + version + '\'' +
                '}';
    }
}

接下来是核心的Stream筛选逻辑,提供两种版本适配不同Java环境:

方案1:使用Java 9+的Version类(推荐,版本比较更准确)

如果项目基于Java 9及以上,直接用java.lang.Version处理版本字符串比较,避免自定义逻辑的漏洞:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        MyObj obj1 = new MyObj("bike", "1.8");
        MyObj obj2 = new MyObj("bike", "2.0");
        MyObj obj3 = new MyObj("car", "3.4");
        MyObj obj4 = new MyObj("car", "4.6");
        List<MyObj> list = new ArrayList<>();
        list.add(obj1);
        list.add(obj2);
        list.add(obj3);
        list.add(obj4);

        // 核心筛选逻辑
        List<MyObj> result = list.stream()
                // 按ID分组
                .collect(Collectors.groupingBy(MyObj::getID))
                .entrySet()
                .stream()
                // 对每个ID组筛选版本最高的对象
                .map(entry -> entry.getValue().stream()
                        .max(Comparator.comparing(obj -> Version.parse(obj.getVersion())))
                        .orElse(null))
                .filter(obj -> obj != null)
                .collect(Collectors.toList());

        // 输出结果:[MyObj{ID='bike', version='2.0'}, MyObj{ID='car', version='4.6'}]
        System.out.println(result);
    }
}

方案2:自定义版本比较器(兼容Java 8)

如果必须用Java 8,自定义版本字符串的比较逻辑,拆分版本号数字段逐一对比:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        MyObj obj1 = new MyObj("bike", "1.8");
        MyObj obj2 = new MyObj("bike", "2.0");
        MyObj obj3 = new MyObj("car", "3.4");
        MyObj obj4 = new MyObj("car", "4.6");
        List<MyObj> list = new ArrayList<>();
        list.add(obj1);
        list.add(obj2);
        list.add(obj3);
        list.add(obj4);

        // 自定义版本比较器
        Comparator<MyObj> versionComparator = (objA, objB) -> {
            String[] v1 = objA.getVersion().split("\\.");
            String[] v2 = objB.getVersion().split("\\.");
            int minLength = Math.min(v1.length, v2.length);
            for (int i = 0; i < minLength; i++) {
                int num1 = Integer.parseInt(v1[i]);
                int num2 = Integer.parseInt(v2[i]);
                if (num1 != num2) {
                    return Integer.compare(num1, num2);
                }
            }
            // 前缀相同时,段数多的版本更高(如1.2.1 > 1.2)
            return Integer.compare(v1.length, v2.length);
        };

        // 核心筛选逻辑
        List<MyObj> result = list.stream()
                .collect(Collectors.groupingBy(MyObj::getID))
                .entrySet()
                .stream()
                .map(entry -> entry.getValue().stream()
                        .max(versionComparator)
                        .orElse(null))
                .filter(obj -> obj != null)
                .collect(Collectors.toList());

        // 输出结果:[MyObj{ID='bike', version='2.0'}, MyObj{ID='car', version='4.6'}]
        System.out.println(result);
    }
}

逻辑说明

  1. 分组:通过groupingBy(MyObj::getID)把列表按ID拆分,每个组对应同一个ID的所有对象。
  2. 取最大值:对每个分组内的对象,用max()方法结合版本比较器,选出版本最高的实例。
  3. 收集结果:将所有分组的最高版本对象汇总成最终列表。

内容的提问来源于stack exchange,提问作者JavaLearner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:33:18