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

如何将Java循环实现的汽车数据聚合代码改写为Stream流?

Java Stream实现按CarNum分组并按车辆类型聚合生成Output对象

核心实现思路

通过Collectors.groupingBy按carNum分组,再结合Collectors.collectingAndThen将每个分组的Car列表转换为Output对象。提供两种实现方案,分别适配不同场景的性能和可读性需求。


方案1:单次遍历分组列表(性能优先,与原循环逻辑对齐)

这种方式和原有循环实现逻辑一致,仅遍历一次分组后的Car列表,避免多次流操作的额外开销,适合大数据量场景:

import java.util.*;
import java.util.stream.Collectors;

// 初始化车辆类型限定集合(建议定义为static final,保证复用性和查询性能)
private static final Set<String> SEDAN_QUALIFIER_SET = new HashSet<>(Arrays.asList("Sedan", "Hatchback"));
private static final Set<String> SUV_QUALIFIER_SET = new HashSet<>(Arrays.asList("SUV", "MPV"));
private static final Set<String> TRUCK_QUALIFIER_SET = new HashSet<>(Arrays.asList("Van", "Truck", "Truck-LD"));

public Map<Long, Output> convertToOutput(List<Car> cdList) {
    return cdList.stream()
        .collect(Collectors.groupingBy(
            Car::getCarNum,
            Collectors.collectingAndThen(
                Collectors.toList(),
                cars -> {
                    Output output = new Output();
                    output.setCarNum(cars.get(0).getCarNum());
                    
                    List<String> sedanEngines = new ArrayList<>();
                    List<String> suvCombined = new ArrayList<>();
                    List<String> truckCombined = new ArrayList<>();
                    
                    // 单次遍历收集所有类型的目标数据
                    for (Car car : cars) {
                        if (SEDAN_QUALIFIER_SET.contains(car.getCartype())) {
                            sedanEngines.add(car.getCarEngine());
                        } else if (SUV_QUALIFIER_SET.contains(car.getCartype())) {
                            suvCombined.add(car.getCarEngine() + "_" + car.getCarName());
                        } else if (TRUCK_QUALIFIER_SET.contains(car.getCartype())) {
                            truckCombined.add(car.getCarEngine() + "_" + car.getCarName());
                        }
                    }
                    
                    // 拼接字符串,空列表自动生成空字符串,符合预期输出
                    output.setCarCode(String.join(",", sedanEngines));
                    output.setCarNameWithEngine(String.join(",", suvCombined));
                    output.setCarChasisInfo(String.join(",", truckCombined));
                    
                    return output;
                }
            )
        ));
}

方案2:多流遍历实现(可读性优先,适合小数据量)

如果分组数据量较小,可通过多次流操作分别过滤、映射各类车辆数据,代码结构更清晰:

public Map<Long, Output> convertToOutput(List<Car> cdList) {
    return cdList.stream()
        .collect(Collectors.groupingBy(
            Car::getCarNum,
            Collectors.collectingAndThen(
                Collectors.toList(),
                cars -> {
                    Output output = new Output();
                    output.setCarNum(cars.get(0).getCarNum());
                    
                    // 收集Sedan/Hatchback类型的engine字段
                    String sedanEngineStr = cars.stream()
                        .filter(car -> SEDAN_QUALIFIER_SET.contains(car.getCartype()))
                        .map(Car::getCarEngine)
                        .collect(Collectors.joining(","));
                    
                    // 收集SUV/MPV类型的engine_name拼接结果
                    String suvCombinedStr = cars.stream()
                        .filter(car -> SUV_QUALIFIER_SET.contains(car.getCartype()))
                        .map(car -> car.getCarEngine() + "_" + car.getCarName())
                        .collect(Collectors.joining(","));
                    
                    // 收集Truck/Van/Truck-LD类型的engine_name拼接结果
                    String truckCombinedStr = cars.stream()
                        .filter(car -> TRUCK_QUALIFIER_SET.contains(car.getCartype()))
                        .map(car -> car.getCarEngine() + "_" + car.getCarName())
                        .collect(Collectors.joining(","));
                    
                    output.setCarCode(sedanEngineStr);
                    output.setCarNameWithEngine(suvCombinedStr);
                    output.setCarChasisInfo(truckCombinedStr);
                    
                    return output;
                }
            )
        ));
}

关键注意事项

  1. 类方法依赖:确保Car类存在对应的getter方法(getCarNum()、getCarEngine()、getCarName()、getCartype()),Output类提供无参构造和setter方法。
  2. 空值处理:两种方案均通过Collectors.joining或String.join处理空列表,自动生成空字符串,完全匹配预期输出要求。
  3. 集合优化:车辆类型限定集合使用HashSet保证O(1)的查询性能,定义为static final避免重复初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:35:03