Java中无需双层for循环合并两类关联对象数组的最优实现方法
实现思路
通过哈希表预索引的方式避免双层循环,整体时间复杂度为O(n+m)(n为B中productAvail列表长度,m为A中products列表长度),仅需要两次单层遍历即可完成合并,性能远高于双层遍历方案。
实现步骤
- 把类B的
productAvail列表转换为prodId为key、ProductAvail对象为value的HashMap,仅需遍历一次B的库存列表 - 遍历类A的
products列表,直接通过prodId从预先生成的HashMap中取出对应的库存信息,组装为Catalog对象 - 所有Catalog对象组装完成后,存入类C的列表中即可
代码示例
默认所有POJO类已经生成对应的getter、setter、构造方法:
import java.util.*; import java.util.stream.Collectors; public class MergeHelper { public C merge(A a, B b) { // 预构建prodId到ProductAvail的映射 Map<String, ProductAvail> availMap = b.getProductAvail() .stream() // 第三个参数为冲突处理函数,遇到重复prodId时保留新条目,按需调整 .collect(Collectors.toMap(ProductAvail::getProdId, item -> item, (oldV, newV) -> newV)); // 遍历Product列表组装Catalog List<Catalog> catalogList = a.getProducts() .stream() .map(product -> { ProductAvail avail = availMap.get(product.getProdId()); // 此处可加非空判断,处理prodId匹配不到的场景 return new Catalog( product.getProdId(), product.getColor(), product.getSize(), avail.getAvailability(), avail.getRegion() ); }) .collect(Collectors.toList()); // 组装返回类C对象 C result = new C(); result.setId(a.getId()); // 如需取B的ID修改为b.getId()即可,按业务需求调整 result.setCatalog(catalogList); return result; } }
补充说明
- 如果不想使用Stream API,用普通的单层for循环实现Map构建和列表组装逻辑也完全可行,核心思路都是预索引避免嵌套循环
- 遇到prodId在A中存在但B中不存在的场景,可以在取avail之后加非空判断,给availability、region设置默认值或者抛出业务异常,按需调整即可
- 数据量越大,这种方案的性能优势越明显,远优于嵌套for循环的O(n*m)时间复杂度方案
内容的提问来源于stack exchange,提问作者miteshgoplani
相关产品推荐
相关产品推荐

