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

Java Stream中基于双条件过滤数据的实现方法

问题:按carNum去重并优先保留carEngine非空的记录

定义的Car类

public class Car {
    Long carNum;
    String carEngine;
    
    // 假设存在对应的getter方法:getCarNum()、getCarEngine()
}

原始数据列表

原始List中的Car数据如下:

Car(carNum=1, carEngine=S02K), 
Car(carNum=1, carEngine=null), 
Car(carNum=2, carEngine=null),
Car(carNum=2, carEngine=S9K),
Car(carNum=3, carEngine=null)

需求说明

需要过滤出满足以下条件的Car列表:

  • 每个carNum唯一,无重复
  • 同一carNum存在多条记录时,选取carEngine不为null的记录
  • 某carNum仅存在一条记录且carEngine为null时,保留该记录

现有实现的问题

当前使用distinctByKey方法按carNum去重:

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
}

调用方式:

carList.stream().filter(distinctByKey(Car::getCarNum)).collect(Collectors.toList());

该实现的问题是:去重逻辑仅根据carNum第一次出现的顺序保留记录,如果同一carNum的记录中,carEngine为null的先出现,就会被保留,而跳过后面非null的记录,无法满足需求。


解决方案

方案一:分组后筛选每组最优记录

通过groupingBy按carNum分组,再对每个分组筛选符合要求的记录,逻辑清晰且不依赖原始数据顺序:

List<Car> result = carList.stream()
    // 按carNum分组,key为carNum,value为对应Car的列表
    .collect(Collectors.groupingBy(Car::getCarNum))
    .values() // 取出所有分组的Car列表
    .stream()
    // 处理每个分组:优先选carEngine非null的,没有则保留第一条
    .map(group -> group.stream()
        .filter(car -> car.getCarEngine() != null)
        .findFirst()
        .orElse(group.get(0)))
    .collect(Collectors.toList());

方案二:先排序再去重

先对列表排序,让同一carNum下carEngine非null的记录排在前面,再用原有的distinctByKey去重:

List<Car> result = carList.stream()
    // 排序规则:carEngine非null的排在同carNum记录的前面
    .sorted((c1, c2) -> {
        if (c1.getCarEngine() != null && c2.getCarEngine() == null) {
            return -1;
        } else if (c1.getCarEngine() == null && c2.getCarEngine() != null) {
            return 1;
        }
        return 0;
    })
    .filter(distinctByKey(Car::getCarNum))
    .collect(Collectors.toList());

两种方案最终都会得到预期输出:

Car(carNum=1, carEngine=S02K), 
Car(carNum=2, carEngine=S9K),
Car(carNum=3, carEngine=null)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:35:12