- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
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/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!