如何优化CarModel属性映射代码的执行性能?
现有如下Java实体类:
class CarModel { private long carKey; private String carName; private CarColor carColor; private CarEngine carEngine; // 省略getter、setter方法 } class CarColor { private long carKey; private String carPrimaryColor; private String carSecondaryColor; // 省略getter、setter方法 } class CarEngine { private long carKey; private String carEnginePartNumber; private String carEngineTransmissionFluid; // 省略getter、setter方法 }
业务场景:从数据库获取仅包含carKey和carName的CarModel列表,再获取CarColor与CarEngine数据列表,转换后赋值给CarModel以完成数据库表更新。当前使用以下addList方法实现属性映射:
private void addList(List<?> list, List<CarModel> carModelList) { carModelList.stream().forEach(x -> { for (Object object : list) { if (object instanceof CarColor && ((CarColor) object).getCarKey() == x.getCarKey()) { x.setCarColor(((CarColor) object)); break; } if (object instanceof CarEngine && ((CarEngine) object).getCarKey() == x.getCarKey()) { x.setCarEngine(((CarEngine) object)); break; } } }); }
该代码可正常运行,但希望提升addList方法的执行效率,有哪些优化方案?
原方法的时间复杂度为O(n*m)(n为CarModel数量,m为传入列表的元素总数),嵌套循环+频繁类型判断会导致数据量较大时效率骤降,以下是针对性优化方案:
1. 预先构建哈希映射(核心优化)
将CarColor和CarEngine分别转换为以carKey为键的Map,用O(1)的哈希查找替换O(m)的遍历,整体时间复杂度降至O(n + m),这是最有效的内存层面优化。
示例代码:
// 构建颜色数据的哈希映射 private Map<Long, CarColor> buildColorMap(List<CarColor> colorList) { return colorList.stream() .collect(Collectors.toMap(CarColor::getCarKey, color -> color)); } // 构建引擎数据的哈希映射 private Map<Long, CarEngine> buildEngineMap(List<CarEngine> engineList) { return engineList.stream() .collect(Collectors.toMap(CarEngine::getCarKey, engine -> engine)); } // 给CarModel批量赋值关联数据 private void enrichCarModels(List<CarModel> carModelList, Map<Long, CarColor> colorMap, Map<Long, CarEngine> engineMap) { carModelList.forEach(car -> { long key = car.getCarKey(); car.setCarColor(colorMap.get(key)); car.setCarEngine(engineMap.get(key)); }); } // 调用示例 List<CarModel> carModels = ...; // 从数据库获取的基础CarModel列表 List<CarColor> colorList = ...; // 从数据库获取的CarColor列表 List<CarEngine> engineList = ...; // 从数据库获取的CarEngine列表 Map<Long, CarColor> colorMap = buildColorMap(colorList); Map<Long, CarEngine> engineMap = buildEngineMap(engineList); enrichCarModels(carModels, colorMap, engineMap);
2. 拆分方法职责,消除类型判断
原方法接收List<?>并通过instanceof判断类型,既增加性能损耗又降低代码可读性。拆分后分别处理不同类型的数据,完全避免不必要的类型检查和强制转换。
3. 并行流优化(适用于大数据量场景)
如果CarModel列表数据量极大(比如十万级以上),且setCarColor/setCarEngine是线程安全操作,可以使用并行流利用多线程提升处理速度:
private void enrichCarModels(List<CarModel> carModelList, Map<Long, CarColor> colorMap, Map<Long, CarEngine> engineMap) { carModelList.parallelStream().forEach(car -> { long key = car.getCarKey(); car.setCarColor(colorMap.get(key)); car.setCarEngine(engineMap.get(key)); }); }
注意:并行流会引入线程切换开销,小数据量场景下反而可能变慢,需根据实际数据量选择。
4. 数据库层面优化(根源优化)
如果业务允许,直接在数据库查询时通过JOIN关联三张表,一次性获取完整的CarModel数据,完全避免后续内存中的数据拼接,这是效率最高的方案。
示例SQL(假设表名分别为car_model、car_color、car_engine):
SELECT cm.car_key, cm.car_name, cc.car_primary_color, cc.car_secondary_color, ce.car_engine_part_number, ce.car_engine_transmission_fluid FROM car_model cm LEFT JOIN car_color cc ON cm.car_key = cc.car_key LEFT JOIN car_engine ce ON cm.car_key = ce.car_key;
查询结果直接映射为完整的CarModel对象,无需后续内存操作。
内容的提问来源于stack exchange,提问作者Vamsi

