如何遍历Map中的3个不等长List,按索引交叉取值合并为新List
实现方案
你要的按索引交叉合并的逻辑,用单层循环即可实现,时间复杂度为O(n)(n为三个列表的总元素数),天然支持不等长场景,性能开销极低:
代码实现
import java.util.*; import java.util.Optional; // 业务逻辑部分 List<User> list1 = Optional.ofNullable(map.get("key1")).orElse(Collections.emptyList()); List<User> list2 = Optional.ofNullable(map.get("key2")).orElse(Collections.emptyList()); List<User> list3 = Optional.ofNullable(map.get("key3")).orElse(Collections.emptyList()); // 计算三个列表的最大长度作为循环边界 int maxSize = Math.max(list1.size(), Math.max(list2.size(), list3.size())); // 提前指定结果列表容量,避免自动扩容的性能损耗 List<User> data = new ArrayList<>(list1.size() + list2.size() + list3.size()); for (int idx = 0; idx < maxSize; idx++) { // 按key1->key2->key3的顺序,当前索引存在元素就加入结果 if (idx < list1.size()) { data.add(list1.get(idx)); } if (idx < list2.size()) { data.add(list2.get(idx)); } if (idx < list3.size()) { data.add(list3.get(idx)); } }
说明
- 你之前用三层嵌套循环的逻辑是生成三个列表的笛卡尔积,完全不符合「按同索引位依次取元素」的需求,自然会出现结果错误、性能极差的问题。
- 上面的实现提前做了列表空值处理,哪怕Map里某个key不存在、返回的列表为null也不会出现空指针异常。
- 如果后续要扩展支持更多key的列表合并,只需要把列表放到一个有序集合里统一遍历即可,不用修改循环逻辑:
// 扩展为支持任意数量有序key的合并逻辑 List<List<User>> allLists = Arrays.asList( Optional.ofNullable(map.get("key1")).orElse(Collections.emptyList()), Optional.ofNullable(map.get("key2")).orElse(Collections.emptyList()), Optional.ofNullable(map.get("key3")).orElse(Collections.emptyList()) // 新增key直接在这里加即可 ); int maxSize = allLists.stream().mapToInt(List::size).max().orElse(0); List<User> data = new ArrayList<>(allLists.stream().mapToInt(List::size).sum()); for (int idx = 0; idx < maxSize; idx++) { for (List<User> list : allLists) { if (idx < list.size()) { data.add(list.get(idx)); } } }
内容的提问来源于stack exchange,提问作者stacky
相关产品推荐
相关产品推荐

