Java中合并两个Map属性生成指定键值对新Map的最佳方法
场景定义
给定两个类定义如下:
class Relationship { long childId; long parentId; } class Person { long id; String name; }
现有两个Map实例:
Map<Long, Relationship> map1; // key=childId,value为对应childId关联的Relationship对象 Map<Long, Person> map2; // key=parentId,value为对应parentId的Person对象
需求为合并两个Map生成新Map:新Map的键为childId,值为该child对应的父级Person对象。已知可通过手写循环实现,需要找JDK或常用工具包中开箱即用的API实现方式。
手写循环的参考伪代码如下:
map3 = new Map<Long, Person>; for each entry e in map1{ Person parent = map2.get(map1.get(e.value().parentId)); map3.put(e.key(), parent); }
实现方案
直接使用JDK 8及以上版本自带的Stream API即可完成,无需引入第三方依赖,属于标准JDK提供的开箱即用能力,实现代码如下:
import java.util.stream.Collectors; // 业务逻辑部分 Map<Long, Person> map3 = map1.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> map2.get(entry.getValue().parentId) ));
适配特殊场景的调整
- 如果存在
map1中的parentId在map2里找不到对应值的情况,可在value映射逻辑中补充空值处理,避免后续触发空指针异常。 - 如果业务场景下可能出现重复
childId,需要给Collectors.toMap传入第三个参数作为重复key的合并规则,否则会抛出IllegalStateException。比如重复key时保留后遍历到的值,写法如下:
Map<Long, Person> map3 = map1.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> map2.get(entry.getValue().parentId), (oldValue, newValue) -> newValue ));
内容的提问来源于stack exchange,提问作者S.Dan
相关产品推荐
相关产品推荐

