如何使用Java Streams API比较后合并两个同类型Box对象列表
原有代码的问题
你写的遍历实现存在两个明显错误:
- 遍历
boxes2的过程中直接调用boxes2.add()新增元素,会触发Java集合的快速失败机制,抛出ConcurrentModificationException - else分支逻辑错误:每匹配到一个boxId不同的box2对象就会新增一次box1,会导致同一个box1被重复添加多次
基于Stream API的正确实现
首先我们先把boxes2转换成boxId对应Box对象的Map,避免每次匹配boxId都遍历整个列表,提升执行效率,再按规则处理合并:
前置假设
你的实体类定义如下(仅列关键getter):
class Char { private String no; private Integer qty; // 省略getter/setter } class Ele { private String eleId; private List<Char> chars; // 省略getter/setter } class Box { private String boxId; private List<Ele> ele; // 省略getter/setter }
实现代码
import java.util.function.Function; import java.util.stream.Collectors; // 第一步:将boxes2转为boxId到Box对象的映射 Map<String, Box> boxIdMap = boxes2.stream() .collect(Collectors.toMap(Box::getBoxId, Function.identity())); // 第二步:遍历boxes1按规则合并 boxes1.forEach(box1 -> { Box matchedBox = boxIdMap.get(box1.getBoxId()); if (matchedBox != null) { // 同boxId匹配成功,构建eleId到Ele对象的映射 Map<String, Ele> eleIdMap = matchedBox.getEle().stream() .collect(Collectors.toMap(Ele::getEleId, Function.identity())); // 遍历box1的ele,匹配到同eleId就追加chars box1.getEle().forEach(ele1 -> { Ele matchedEle = eleIdMap.get(ele1.getEleId()); if (matchedEle != null) { matchedEle.getChars().addAll(ele1.getChars()); } // 若需要把box1独有的ele也添加到box2,可加else分支:else matchedBox.getEle().add(ele1); }); } else { // boxId不存在,直接把整个box1添加到boxes2 boxes2.add(box1); } });
执行完成后boxes2就是你需要的合并后结果,和你给出的示例效果完全一致。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

