地图上的Java8流媒体
我有一张地图,我想在上面流淌地图上的Java8流媒体,java,java-8,java-stream,Java,Java 8,Java Stream,我有一张地图,我想在上面流淌 Map<LocalDate, Map<Integer, List<String>>> mainMap; 而childMap包含 {2016-02-23={120=[1,2,3], 121=[1,2,3], 122=[1,2,3], 123=[1,2,3]}} {2016-02-23=[120,123]} 我想从mainMap中删除这些值 预期产出=> {2016-02-23={121=[1,2,3], 122=[1,2,3]
Map<LocalDate, Map<Integer, List<String>>> mainMap;
而childMap包含
{2016-02-23={120=[1,2,3], 121=[1,2,3], 122=[1,2,3], 123=[1,2,3]}}
{2016-02-23=[120,123]}
我想从mainMap中删除这些值
预期产出=>
{2016-02-23={121=[1,2,3], 122=[1,2,3]}}
如何在Java 8中执行此操作?您可以通过以下方法执行此操作:
mainMap.forEach((k, v) ->
v.keySet().removeIf(s ->
Optional.ofNullable(childMap.get(k)).map(o -> o.contains(s.toString())).orElse(false)
)
);
这将遍历mainMap
。然后,关于该映射的值,即映射
,它删除所有整数键(转换为字符串
),其中当前日期的子映射
指向包含该键的列表。请注意,如果子映射不包含当前日期的列表,则不会删除整数键
完整的示例代码如下所示,用于打印所需的输出:
public static void main(String[] args) {
Map<LocalDate, Map<Integer, List<String>>> mainMap = new HashMap<>();
Map<Integer, List<String>> map = new HashMap<>();
map.put(120, Arrays.asList("1", "2", "3"));
map.put(121, Arrays.asList("1", "2", "3"));
map.put(122, Arrays.asList("1", "2", "3"));
map.put(123, Arrays.asList("1", "2", "3"));
mainMap.put(LocalDate.of(2016, 2, 23), map);
Map<LocalDate, List<String>> childMap = new HashMap<>();
childMap.put(LocalDate.of(2016, 2, 23), Arrays.asList("120", "123"));
mainMap.forEach((k, v) ->
v.keySet().removeIf(s ->
Optional.ofNullable(childMap.get(k)).map(o -> o.contains(s.toString())).orElse(false)
)
);
System.out.println(mainMap);
}
publicstaticvoidmain(字符串[]args){
Map mainMap=新的HashMap();
Map Map=newhashmap();
map.put(120,数组.asList(“1”、“2”、“3”);
map.put(121,数组.asList(“1”、“2”、“3”);
map.put(122,数组.asList(“1”、“2”、“3”);
map.put(123,数组.asList(“1”、“2”、“3”);
mainMap.put(LocalDate.of(2016,2,23),map);
Map childMap=newhashmap();
childMap.put(LocalDate.of(2016,2,23),Arrays.asList(“120”,“123”);
主地图forEach((k,v)->
v、 键集().removeIf(s->
可选.ofNullable(childMap.get(k)).map(o->o.contains(s.toString()).orElse(false)
)
);
System.out.println(主地图);
}
is的替代方案
不同之处在于,Tunaki的解决方案将迭代mainMap
中包含的子映射的内容,并对每个子映射执行childMap
查找,而上述解决方案将迭代childMap
中找到的列表,并对mainMap
的子映射执行查找。当子贴图和列表的大小都增大时,这是最好的
有一件事还没有解决,那就是如果mainMap
的子映射由于操作而被清空,是否应该删除它们的映射。在对要修改的映射进行迭代时,不可能一次删除外部映射(除非使用迭代器求助于旧循环)
解决方案是迭代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
s到mainMap
的Integer
s之间的转换。如果它们具有相同的类型,例如,如果childMap
是Map
或mainMap
是Map
,则不删除空映射的解决方案非常简单
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=[120121122123]}
,那么输出会是什么?我的观点是。。。外部地图的输入会发生什么?它必须是空映射还是也必须删除映射到空内部映射的条目?如果childMap为{2016-02-23=[120121122123]},输出将是什么?我的观点是。。。外部地图的输入会发生什么?它必须是一个空映射,还是您也必须删除映射到空内部映射的条目?(我问了OP同样的问题)@Federicoperaltachaffner这是个好问题。OP并没有具体说明那个案例。我的回答会产生一张空的内心地图。您可以通过调用mainMap.values().removeIf(Map::isEmpty)来考虑这一点代码>在forEach
之后。
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));