为什么Map.of不允许空键和值? [英] Why does Map.of not allow null keys and values?

查看:157
本文介绍了为什么Map.of不允许空键和值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Java 9,已为 List Set 地图接口。这些方法允许快速实例化一行中包含值的Map对象。现在,如果我们考虑:

  Map< Integer,String> map1 = new HashMap< Integer,String>(Map.of(1, value1,2, value2,3, value3)); 
map1.put(4,null);

如果我们这样做,则以上内容无任何例外:

  Map< Integer,String> map2 = Map.of(1, value1,2, value2,3, value3,4,null); 

它抛出:

 线程主中的异常java.lang.NullPointerException 
at java.base / java.util.Objects.requireNonNull(Objects.java:221)
..

我无法获取,为什么在第二种情况下不允许为空



我知道HashMap可以将null作为键和值,但是为什么在Map.of的情况下限制了此值?



java.util.Set.of( v1, v2,null) java.util.List.of( v1, v2,null)

解决方案

正如其他人指出的那样, Map 合同允许拒绝空值...


[ S]一些实现禁止 null 键和值[...]。尝试插入不合格的键或值会引发未经检查的异常,通常是 NullPointerException ClassCastException


...和收集工厂(不仅仅是在地图上)使用它


他们不允许 null 键和值。尝试使用 null 键或值创建它们会导致 NullPointerException



但是为什么呢?


在集合中允许 null 现在被视为设计错误。这有多种原因。一个很好的方面就是可用性,其中最著名的麻烦制造者是 Map :: get 。如果返回 null ,则不清楚密钥是否丢失或值是 null 。一般来说,保证 null 免费的集合更易于使用。在实现方面,它们还需要较少的特殊大小写,从而使代码更易于维护且性能更高。


您可以听Stuart Marks的解释在本次演讲中,但 JEP 269 (介绍了工厂方法的人)也对其进行了总结:


Null元素,键和值将被禁止。 (最近没有引入的集合不支持空值。)此外,禁止空值提供了更紧凑的内部表示,更快的访问权限和更少的特殊情况的机会。


由于 HashMap 在被缓慢发现时已经泛滥了,因此在不破坏现有代码的情况下进行更改为时已晚,但是这些接口的最新实现(例如 ConcurrentHashMap )不再允许 null ,并且工厂方法的新集合也不例外。


(I认为另一个原因是,显式地使用 null 值被视为可能的实现错误,但我错了。那将要复制键,这也是非法的。) / p>

所以不允许 null 有一些技术原因,但也没有e使用创建的集合来提高代码的健壮性。


With Java 9, new factory methods have been introduced for the List, Set and Map interfaces. These methods allow quickly instantiating a Map object with values in one line. Now, if we consider:

Map<Integer, String> map1 = new HashMap<Integer, String>(Map.of(1, "value1", 2, "value2", 3, "value3"));
map1.put(4, null);

The above is allowed without any exception while if we do:

Map<Integer, String> map2 = Map.of(1, "value1", 2, "value2", 3, "value3", 4, null );

It throws:

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:221)
..

I am not able to get, why null is not allowed in second case.

I know HashMap can take null as a key as well as a value but why was that restricted in the case of Map.of?

The same thing happens in the case of java.util.Set.of("v1", "v2", null) and java.util.List.of("v1", "v2", null).

解决方案

As others pointed out, the Map contract allows rejecting nulls...

[S]ome implementations prohibit null keys and values [...]. Attempting to insert an ineligible key or value throws an unchecked exception, typically NullPointerException or ClassCastException.

... and the collection factories (not just on maps) make use of that.

They disallow null keys and values. Attempts to create them with null keys or values result in NullPointerException.

But why?

Allowing null in collections is by now seen as a design error. This has a variety of reasons. A good one is usability, where the most prominent trouble maker is Map::get. If it returns null, it is unclear whether the key is missing or the value was null. Generally speaking, collections that are guaranteed null free are easier to use. Implementation-wise, they also require less special casing, making the code easier to maintain and more performant.

You can listen to Stuart Marks explain it in this talk but JEP 269 (the one that introduced the factory methods) summarizes it as well:

Null elements, keys, and values will be disallowed. (No recently introduced collections have supported nulls.) In addition, prohibiting nulls offers opportunities for a more compact internal representation, faster access, and fewer special cases.

Since HashMap was already out in the wild when this was slowly discovered, it was too late to change it without breaking existing code but most recent implementations of those interfaces (e.g. ConcurrentHashMap) do not allow null anymore and the new collections for the factory methods are no exception.

(I thought another reason was that explicitly using null values was seen as a likely implementation error but I got that wrong. That was about to duplicate keys, which are illegal as well.)

So disallowing null had some technical reason but it was also done to improve the robustness of the code using the created collections.

这篇关于为什么Map.of不允许空键和值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆