有一种观点认为在关系数据库中不应该允许空值.也就是说,表的属性(列)不应该允许空值.来自软件开发背景,我真的不明白这一点.似乎如果null在属性的上下文中有效,那么应该允许它.这在Java中非常常见,其中对象引用通常为null.没有广泛的数据库经验,我想知道我是否在这里遗漏了一些东西.
让我们考虑一个Parent只包含一个Integer属性的类.我创建了6个父类对象,属性值为100, 20, 300, 400, 500, null.
现在我将所有对象添加到列表中(列表名称是列表).然后我想得到属性值大于的对象100.我为此目的使用了Java 8流.
Predicate<Entity> predicate = e -> e.getParentId() < 100;
result = list.stream().filter(predicate).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我还想按降序对列表进行排序.我为此目的使用了以下代码.
Comparator<Entity> comp = (d1,d2) -> d2.getId().compareTo(d1.getId());
list.sort(comp);
Run Code Online (Sandbox Code Playgroud)
在这两种情况下我都得到了NullPointerException.
怎么办呢?
该Set接口不承诺实现是否允许null元素.每个实现都应该在其文档中声明.
Collectors.toSet()承诺回报的实现Set,但明确地让"无担保的类型,可变性,串行化,或线程安全Set返回".没有提到空安全性.
目前执行Collectors.toSet()中的OpenJDK总是使用HashSet,允许null元素,但是这可能在未来改变和其他实施方式可以做出不同的.
如果某个Set实现禁止null元素,它会NullPointerException在不同时间抛出,特别是在尝试时add(null).似乎如果Collectors.toSet()决定使用null不容忍的Set实现,则调用stream.collect(Collectors.toSet())一个Stream 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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有,那么我假设在使用Collectors.toSet()或准备好处理之前我们应该始终确保流不包含空值NullPointerException.(这是例外单独够有关系吗?)或者,当这是不可接受的或硬的,我们可以要求使用类似的代码一组特定的实现Collectors.toCollection(HashSet::new).
编辑:有一个现有的问题,听起来表面上相似,这个问题被关闭作为一个假设的副本.但是,相关问题根本没有解决Collectors.toSet().此外,该问题的答案构成了我的问题的 …