所以我正在尝试使用Java 8流Collectors.toMap将元素添加到新创建的Map中。
要创建的映射可能包含其某些键的空值。这对于 HashMap 来说是完全可以接受的,当我使用 for Each 的流来添加成员时,它按预期工作:
final Map<String, Method> rMap = new HashMap<> ( );
msgRouteProps.entrySet ( )
.stream ( )
.forEach (entry -> rMap.put (entry.getKey ( ),
ReflectionUtil.getNamedMethod (processor, entry.getValue ( ))));
msgRouteProps 是一个映射,其中键和值都是非空的。请注意,ReflectionUtil.getNamedMethod (( 调用可能会返回一个 null,我希望将其放入生成的 Map 中。
所以我想探索如何使用 Collectors.toMap(( 方法做同样的事情,这样流操作就可以返回新创建的映射,而无需我直接创建它。
所以我尝试了以下方法:
Map<String, Method> rMap =
msgRouteProps.entrySet ( )
.stream ( )
.collect (Collectors.toMap (Map.Entry::getKey,
(e) -> ReflectionUtil.getNamedMethod (processor, e.getValue ( ))));
在我看来,这应该以同样的方式工作,但不幸的是,它失败并出现空指针异常。看起来 Collectors.toMap 方法调用了 HashMap 的 merge(( 方法,该方法不允许传递空值。对我来说似乎很奇怪的是,我真的不认为在这种情况下应该调用合并,因为原始映射中的键都是唯一的。鉴于此,我假设可以通过调用地图的 put(( 方法简单地将这些值添加到新地图中,该方法将允许空值。
是我在这里做错了什么,还是有解决方法?或者这只是使用 Collectors.toMap 时的预期行为?
最好的方法是在具有空值时使用 forEach。仍然如果您想使用collect
请尝试以下解决方法
Map<String, Method> rMap =
msgRouteProps.entrySet()
.stream()
.collect(HashMap::new, (m,v) -> m.put(v.getKey(), ReflectionUtil.getNamedMethod(processor, v.getValue())), HashMap::putAll);
也看看这个答案