哪些java集合接受添加null值



我知道Set and Map接受null值,今天我刚刚发现LinkedList也接受像这样的null值

map.put(null, 1);
set.add(null);
linkedList.add(null)

是否有其他允许存储null值的集合?。只是为了在一个地方获得一个全面的列表,并为每个列表列出原因。

SetMap是接口。它们有几个Java实现。

Map的流行实现有:

  1. HashMap-接受一个null密钥
  2. Hashtable-不接受任何null密钥
  3. TreeMap-不接受任何null密钥
  4. LinkedHashMap-接受一个null密钥

在上述任何实现中,任何数量的null值都可以添加为


Set的流行实现有:

  1. HashSet-接受一个null元素
  2. TreeSet-不接受任何null元素
  3. LinkedHashSet-接受一个null元素

List的任何实现,如ArrayListLinkedList,都可以接受nulls。

这个问题可以通过使用JDK中的占位符类Optional来解决。

其原理是使用将携带值(也为null值(的Optional类将可为null的值封装在包装器实例中。

它可能很烦人,代码也有点重,但在许多情况下肯定是合适的。

以下是一个非零值的示例:

Optional<Integer> valuedInt = Optional.ofNullable(123);
assertTrue(valuedInt.isPresent());          
assertEquals(Integer.valueOf(123), valuedInt.get());

这里有一个空值的例子:

Optional<Integer> nullInt = Optional.ofNullable(null);
assertTrue(nullInt.isEmpty());
try {
var val = nullInt.get();
} catch (Exception e) {
// Invocation of nullInt.get() throws an exception.
assertTrue(e instanceof NoSuchElementException);
}

// However, the method Optional.orElse(T) can be used as
// a getter that supplies the value wether it is valued or null.
assertEquals(Integer.valueOf(123), valuedInt.orElse(null));
assertEquals(null,                 nullInt.orElse(null));

我们可以初始化列表如下:

// Our hacked list
List<Optional<Integer>> integersOpt;

填充列表的第一种方法:

integersOpt = new ArrayList<>();
integersOpt.add(Optional.ofNullable(1));
integersOpt.add(Optional.ofNullable(null));
integersOpt.add(Optional.ofNullable(2));
integersOpt.add(Optional.ofNullable(null));
integersOpt.add(Optional.ofNullable(3));

填充列表的第二种方法(不可修改(:

integersOpt =
Arrays.asList(1, null, 2, null, 3).stream()
.map(x -> Optional.ofNullable(x))
.collect(Collectors.toList());

填充列表的第三种方式(可修改(:

integersOpt =
new ArrayList<>(
Arrays.asList(1, null, 2, null, 3).stream()
.map(x -> Optional.ofNullable(x))
.collect(Collectors.toList())
);

计数和打印值:

int countNulls = 0, countNonNulls = 0;
for(Optional<Integer> opt : integersOpt) {
Integer optVal = opt.orElse(null); // Our famous "getter" function.
if(optVal == null) {countNulls++;}
else               {countNonNulls++;}
System.out.println("Original value = " + optVal);
}
assertEquals(2, countNulls);
assertEquals(3, countNonNulls);

integersOpt.toString()将返回此值:

[Optional[1], Optional.empty, Optional[2], Optional.empty, Optional[3]]

时间证明,接受null是一个设计错误。首先,这会使实现变得复杂,因为在某个时间点,您可能需要能够比较nullnull;这有时需要特殊的处理(或者至少在代码中有特殊的分支(。

自java-9以来,不可变集合都拒绝null,甚至正确地记录它。一个小例子(但还有更多(是Set:of,它说:

@throws NullPointerException如果元素为空

不仅如此,他们还不允许null检查,所以你可能会对此感到惊讶:

Set<Object> oldS = new HashSet<>();
oldS.add(new Object());
System.out.println(oldS.contains(null)); // false
Set<Object> newS = Set.of(new Object());
System.out.println(newS.contains(null)); // NPE

JDK中的每一个新集合或实现都禁止null

相关内容

  • 没有找到相关文章

最新更新