Map.of()与Collections.emptyMap()

msa*_*yag 17 java collections java-9

Map.of()Collections.emptyMap()之间List.of(),Collections.emptyList()和之间Set.of()和之间是否存在差异Collections.emptySet()

jar*_*bjo 20

是的,甚至还有一些行为,而不是通过返回的集合彼此只是技术上的差异emptyXyz在工厂方法Collections类和新of的接口(介绍工厂方法Map,List,Set)与JDK 9,如果这些不带参数调用.

相关的区别是新of工厂方法返回的集合不允许null键和值(如List,SetMap接口中的API文档中所指出的).这对于空集合来说可能听起来不那么重要,但即使它没有很清楚地记录,即使新集合实现中的访问器方法也检查空值.

一些不同的例子:

Collections.emptyList().contains(null)将返回false,同时List.of().contains(null)将抛出一个NullPointerException.

Collection.emptyMap().getOrDefault(null, V)会回来V,而Map.of().getOrDefault(null, V)会抛出一个NullPointerException.

正如目前在Oracle的JDK 9中实现的那样,新工厂方法返回的集合中的至少以下方法将抛出NullPointerExceptions,但表现得"理智"(如最初设计和指定集合类以支持null键和值)使用类中的旧工厂方法Collections:

  • List.of().contains(null);
  • Set.of().contains(null);
  • Map.of().containsKey(null);
  • Map.of().containsValue(null);
  • Map.of().getOrDefault(null, <any>);

  • @slim这里没有向后兼容的问题.`X.of()`方法是新的,并不打算直接替换`Collections.emptyX()`方法.现有代码将继续像旧Java版本一样工作. (5认同)
  • 这种行为不是"新的".Map和Set是接口.接口允许不同的实现.某些实现支持空值,而其他实现则不支持.例如,ConcurrentSkipListMap也会在`containsKey(null)`上抛出NPE.界面文档尽可能多地说. (4认同)
  • @Jesper 值得指出的是,你不能进入你的旧代码并在不期望行为改变的情况下用 `Set.of()` 全局替换 `Collections.emptySet()`。特别是因为有几个人(包括我)错误地给出了一个答案,暗示你可以做到这一点。 (2认同)