当前位置: 首页 > 知识库问答 >
问题:

Java8流收集器中断HashMap插入语义学?

潘佐
2023-03-14

所以我试图使用Java8流Collectors.toMap添加元素到新创建的Map。

要创建的映射可能包含其某些键的空值。这对于HashMap来说是完全可以接受的,当我使用stream forEach添加成员时,它会按预期工作:

    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<String, Method> rMap = 
    msgRouteProps.entrySet ( )
                 .stream ( )
                 .collect (Collectors.toMap (Map.Entry::getKey,
                                             (e) -> ReflectionUtil.getNamedMethod (processor, e.getValue ( ))));

在我看来,这应该是同样的工作方式,但不幸的是,它失败了一个空指针异常。看来Collectors.toMap方法调用HashMap的合并()方法,该方法不允许传递空值。对我来说奇怪的是,我真的不认为在这种情况下应该调用合并,因为原始地图中的键都是唯一的。考虑到这一点,我假设这些值可以通过调用map的put()方法简单地添加到新map中,这将允许空值。

是我做错了什么,还是有办法解决这个问题?或者这只是使用Collectors.to映射时的预期行为?

共有1个答案

阎善
2023-03-14

这是一个已知的错误,已经被许多用户报告过

如果有空值,最好的方法是使用forEach。不过,如果您想使用收集,请尝试以下解决方法

Map<String, Method> rMap = 
    msgRouteProps.entrySet()
                 .stream()
                 .collect(HashMap::new, (m,v) -> m.put(v.getKey(), ReflectionUtil.getNamedMethod(processor, v.getValue())), HashMap::putAll);

同时也看看这个答案

 类似资料:
  • 我有一个HashMap,我需要使用一些函数对其进行筛选: 上述代码中的错误是变量的声明类型。应该是而不是。 所以现在的功能代码是:

  • 我有一个练习要解决。我有一个Fox类,它有名称和颜色字段。我的练习是根据颜色找出狐狸的频率。 因此,我创建了一个HashMap,其中String属性将是fox名称,整数将是事件本身: 这样做之后,我一直在尝试用流编写代码,但我很难做到这一点。我写了这样的东西: ,狐狸是一个列表。 我的问题基本上是语法。我想做一件事,如果颜色没有出现,那么 其他的 我应该如何把它放在一起?

  • 我试图对对象中的每个条目执行映射操作。 我需要从键中去掉前缀,并将值从一种类型转换为另一种类型。我的代码从 映射实例并使用,这看起来很难看。 还有更好的选择吗?使用for循环似乎更好: 我应该避免使用流API吗?还是我错过了更好的方式?

  • 问题内容: Java 8中有什么方法可以将一个元素分组而不收集它们?我希望结果再次出现。因为我必须处理大量数据甚至是无限流,所以我无法先收集数据并再次流处理结果。 所有需要分组的元素在第一流中都是连续的。因此,我喜欢使流评估保持懒惰。 问题答案: 无法使用标准Stream API做到这一点。通常,您无法执行此操作,因为将来总是有可能出现属于任何已创建组的新项目,因此,在处理所有输入之前,您无法将组

  • 在Java8中有什么方法可以在中分组元素而不收集它们吗?我希望结果再次成为。因为我必须处理大量的数据,甚至是无限的流,所以我不能首先收集数据,然后再次流化结果。 所有需要分组的元素在第一个流中是连续的。因此,我喜欢保持流评估懒惰。

  • 我有以下课程。 我希望能够按年龄分组,然后收集人名列表,而不是人名对象本身;所有这些都在一个漂亮的lamba表达式中。 为了简化所有这些,我链接了当前的解决方案,该解决方案存储按年龄分组的结果,然后迭代它以收集名称。 当前解决方案 不理想,为了学习,我想有一个更优雅、更高效的解决方案。