合并操作中的HashMap null检查

Pau*_*ric 6 java-8 collectors

为什么HashMap合并正在对值进行空值检查.HashMap支持null键和null值.所以有人可以告诉为什么需要对合并进行null检查?

@Override
public V merge(K key, V value,
               BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    if (value == null)
        throw new NullPointerException();
    if (remappingFunction == null)
        throw new NullPointerException();
Run Code Online (Sandbox Code Playgroud)

由于这个原因,我无法Collectors.toMap(Function.identity(), this::get)用于收集地图中的值

Hol*_*ger 7

该行为是由合同强制执行Map.merge

\n
\n

投掷:

\n

\xe2\x80\xa6

\n

NullPointerException - 如果指定的键为 null 并且此映射不支持 null 键或者值或 remappingFunction 为 null

\n
\n

请注意,使用Map.mergeforCollectors.toMap而不使用合并函数是一个实现细节;它不仅不允许null值,而且不提供报告重复键所需的行为,当存在重复键时,Java\xc2\xa08 实现错误地将两个值之一报告为键。

\n

在Java\xc2\xa09中,实现已经完全重写,不再使用Map.merge。但新的实现是行为兼容的,现在当值为 时,代码会显式抛出nullCollectors.toMap因此,不接受值的行为null已在代码中修复,不再是使用的产物Map.merge。(仍然只谈论toMap没有合并功能的收集器。)

\n

不幸的是,文档没有说明。

\n


Eug*_*ene 4

因为在内部使用了for Collectors.toMap, Map#merge- 你对此无能为力。使用 staticCollectors.toMap不是一个选项(顺便说一句,它被记录为抛出一个NullPointerException)。

但是旋转自定义收集器以能够执行您想要的操作(您尚未显示)并不那么复杂,这是一个示例:

 Map<Integer, Integer> result = Arrays.asList(null, 1, 2, 3)
            .stream()
            .collect(
                    HashMap::new,
                    (map, i) -> {
                        map.put(i, i);
                    },
                    HashMap::putAll);
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,“Collectors.toMap”的文档并没有真正说明“NullPointerException”的内容。顺便说一句,您的 lambda 表达式实际上并不需要花括号。 (6认同)