除了Tunaki的答案,还有以下替代方案:
mainMap.forEach((k, v) -> childMap.getOrDefault(k, emptyList())
.stream().map(Integer::valueOf).forEach(v::remove));
区别在于Tunaki的解决方案将遍历
mainMap
中包含的子地图的内容,并对每个内容执行
childMap
上的查找,而上面的解决方案将遍历
childMap
中找到的列表,并在
mainMap
的子地图中进行查找。当子地图和列表的大小增长时,这种方法更可取。
有一件事还没有解决,即如果由于操作而清空了
mainMap
的子地图,是否应该删除其映射。当迭代要修改的映射时,不可能一次性支持外部映射的删除(除非您使用旧循环并使用
Iterator
)。一种解决方案是先迭代
childMap
。
childMap.forEach((k,v) -> mainMap.computeIfPresent(k, (d,m) -> {
v.stream().map(Integer::valueOf).forEach(m::remove);
return m.isEmpty()? null: m;
}));
请注意,大多数复杂性来自于两个映射之间的类型不匹配,因此必须执行
childMap
的
String
到
mainMap
的
Integer
的转换。如果它们具有相同的类型,例如如果
childMap
是
Map<LocalDate,List<Integer>>
或
mainMap
是
Map<LocalDate,Map<String,List<String>>>
,则不删除空映射的解决方案就像这样简单:
mainMap.forEach((k, v) -> v.keySet().removeAll(childMap.getOrDefault(k, emptyList())));
并且这个解决方案还会从外部地图中删除空映射:
childMap.forEach((k,v) -> mainMap.computeIfPresent(k, (d,m) -> {
m.keySet().removeAll(v);
return m.isEmpty()? null: m;
}));
上面的代码可能会删除最初为空的映射。如果你只想在此操作期间删除映射,即不触及最初为空的映射,则代码变得更简单:
childMap.forEach((k,v) ->
mainMap.computeIfPresent(k, (d,m) -> m.keySet().removeAll(v) && m.isEmpty()? null: m));
childMap
是{2016-02-23=[120,121,122,123]}
,输出会是什么?我的意思是...外部映射的条目会发生什么?它必须是一个空映射还是您必须删除映射到空内部映射的条目? - fps