如何基于输入条件创建动态Java Stream处理相似流逻辑
统一动态处理Car列表的Stream逻辑
你当前的两段Stream代码逻辑高度重复,仅过滤条件和Map键的提取方式不同,完全可以通过提取公共方法实现动态处理,避免冗余代码。
实现思路
把可变的部分(空值检查逻辑、键提取逻辑)抽象成函数参数传入通用方法,固定的合并逻辑可以预定义,再通过一个入口方法根据传入的类型选择对应的逻辑执行。
具体代码实现
首先,编写通用的处理工具类:
import org.springframework.util.ObjectUtils; import java.util.List; import java.util.Map; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; public class CarProcessor { // 通用核心处理方法 private static Map<Object, Car> processCarList(List<Car> carList, Function<Car, Object> keyExtractor, Function<Car, Boolean> nonNullFilter, BinaryOperator<Car> mergeStrategy) { return carList.stream() .filter(nonNullFilter) .collect(Collectors.toMap( keyExtractor, Function.identity(), mergeStrategy )); } // 预定义合并规则(两个场景合并逻辑一致,直接复用) private static final BinaryOperator<Car> ENGINE_MERGE_STRATEGY = (car1, car2) -> { Car mergedCar = new Car(); mergedCar.setCarId(car1.getCarId()); mergedCar.setCarNumber(car1.getCarNumber()); mergedCar.setCarColorId(car1.getCarColorId()); mergedCar.setEngineNumber(car1.getEngineNumber().concat(car2.getEngineNumber())); mergedCar.setPartsNumber(car1.getPartsNumber()); mergedCar.setModifiedBy(car1.getModifiedBy()); return mergedCar; }; // 根据传入的类型字符串执行对应处理 public static Map<Object, Car> processByType(List<Car> carList, String processType) { return switch (processType) { case "carNumber" -> processCarList( carList, Car::getCarNumber, car -> !ObjectUtils.isEmpty(car.getCarNumber()), ENGINE_MERGE_STRATEGY ); case "colorId" -> processCarList( carList, Car::getCarColorId, car -> !ObjectUtils.isEmpty(car.getCarColorId()), ENGINE_MERGE_STRATEGY ); default -> throw new IllegalArgumentException("不支持的处理类型:" + processType); }; } }
调用示例
List<Car> carList = List.of( new Car(1L, 100L, 1000L, "1ACB", "ZEGV200", "John"), new Car(2L, 100L, 1000L, "1TUV", "ZVAV200", "Doe"), new Car(3L, 200L, 2000L, "1ZVC", "CADV200", "Jane"), new Car(4L, 200L, 2000L, "8CEB", "V2IWD00", "Harry") ); // 根据类型动态处理 Map<Object, Car> groupedByCarNumber = CarProcessor.processByType(carList, "carNumber"); Map<Object, Car> groupedByColorId = CarProcessor.processByType(carList, "colorId");
优化建议(可选)
如果想避免字符串类型的拼写错误,可以用枚举来管理处理类型,代码更健壮:
public enum ProcessType { CAR_NUMBER(Car::getCarNumber, car -> !ObjectUtils.isEmpty(car.getCarNumber())), COLOR_ID(Car::getCarColorId, car -> !ObjectUtils.isEmpty(car.getCarColorId())); private final Function<Car, Object> keyExtractor; private final Function<Car, Boolean> nonNullFilter; ProcessType(Function<Car, Object> keyExtractor, Function<Car, Boolean> nonNullFilter) { this.keyExtractor = keyExtractor; this.nonNullFilter = nonNullFilter; } public Function<Car, Object> getKeyExtractor() { return keyExtractor; } public Function<Car, Boolean> getNonNullFilter() { return nonNullFilter; } }
修改CarProcessor的入口方法:
public static Map<Object, Car> processByType(List<Car> carList, ProcessType processType) { return processCarList( carList, processType.getKeyExtractor(), processType.getNonNullFilter(), ENGINE_MERGE_STRATEGY ); }
调用时直接使用枚举:
Map<Object, Car> groupedByColorId = CarProcessor.processByType(carList, ProcessType.COLOR_ID);
内容的提问来源于stack exchange,提问作者Vamsi
相关产品推荐
相关产品推荐

