gpt4 book ai didi

java - Java 的 Collectors.toSet() 是否保证允许空值?

转载 作者:搜寻专家 更新时间:2023-10-30 21:32:38 47 4
gpt4 key购买 nike

Set接口(interface)不 promise 实现是否允许 null 元素。每个实现都应该在其文档中声明这一点。

Collectors.toSet() promise 返回 Set 的实现,但明确“不保证返回的 Set 的类型、可变性、可序列化性或线程安全性”。没有提到空安全。

OpenJDK 中 Collectors.toSet() 的当前实现始终使用 HashSet,它允许空元素,但这在未来可能会改变,其他实现可能会有所不同.

如果 Set 实现禁止 null 元素,它会在不同时间抛出 NullPointerException,特别是在尝试 add(null) 时.看起来如果 Collectors.toSet() 决定使用 null-intolant Set 实现,调用 stream.collect(Collectors.toSet())Stream 流 上会抛出。 collect 的规范没有列出任何异常,Collector 的任何规范也没有。方法。这可能表明 collect 调用允许 stream 中存在空值,但另一方面,尚不清楚这是否真的意味着什么,因为 NullPointerException 是未经检查的异常,严格来说不必列出。

是否在其他地方更清楚地说明了这一点?特别是下面的代码是不是保证不会抛出?是否保证返回 true

import java.util.stream.*;

class Test {
public static boolean setContainsNull() {
return Stream.of("A", "list", "of", null, "strings")
.collect(Collectors.toSet())
.contains(null);
}
}

如果不是,那么我认为在使用 Collectors.toSet() 或准备好处理 NullPointerException 之前,我们应该始终确保流不包含空值。 (但是这个异常(exception)就足够了吗?)或者,当这是 Not Acceptable 或困难的时候,我们可以使用像 Collectors.toCollection(HashSet::new) 这样的代码来请求一个特定的集合实现。

编辑:有一个existing question这听起来表面上很相似,这个问题被认为是那个问题的重复。但是,链接的问题根本没有解决 Collectors.toSet()。此外,该问题的答案构成了我的问题的基本假设。该问题问:流中是否允许空值?是的。 但是当通过标准收集器收集包含空值的(完全允许的)流时会发生什么?

最佳答案

故意未指定的行为(如“类型、可变性、可序列化或线程安全”)与未指定的行为(如 null 支持)之间存在差异。

每当未指定行为时,引用实现的实际行为往往会成为以后无法更改的事实,即使由于兼容性限制而违背初衷,或者至少不能在没有充分理由的情况下被更改。

请注意,虽然没有使用返回真正不可变或不可序列化的 Set 的保留权利,只是因为在 Java 8 版本中不存在这样的类型,强制执行非 null 即使不存在足够的 HashMap 类型,行为也是可能的,就像 groupingBy 禁止 null 键一样,尽管也未指定。

请进一步注意,虽然 groupingBy 收集器在其实现代码中故意拒绝 null 键,但 toMap 是实际行为如何变成的一个很好的例子契约(Contract)的一部分。在 Java 8 中,toMap 允许 null 键但拒绝 null 值,仅仅是因为它调用了 Map.merge那种行为。 It seems, this wasn’t an intended behavior in the first place. 现在,在 Java 9 中,没有合并功能的 toMap 收集器不再使用 Map.merge(JDK-8040892,另见 this answer),但故意拒绝收集器代码中的 null 值,以在行为上与以前的版本兼容。仅仅是因为从未说过 null 行为是有意未指定的。

因此,Collectors.toSet()(以及同样的 Collectors.toList())允许两个主要 Java 版本的 null 值现在和没有规范说你不能认为这是理所当然的,所以你可以很确定这在未来不会改变。

关于java - Java 的 Collectors.toSet() 是否保证允许空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47212902/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com