Java Map.of()与Collections.emptyMap()的比较

Java Map.of()与Collections.emptyMap()的比较,java,collections,java-9,Java,Collections,Java 9,Map.of()和Collections.emptyMap()之间,List.of()和Collections.emptyList()之间,以及Set.of()和Collections.emptySet()之间有什么区别吗?是的,在collections类中的emptyXyz工厂方法返回的集合与使用JDK 9的接口(Map,List,Set)中引入的新工厂方法之间甚至存在行为上的差异,而不仅仅是技术上的差异,如果调用这些函数时没有参数 相关的区别在于,新的of工厂方法返回的集合不允许null键和

Map.of()
Collections.emptyMap()
之间,
List.of()
Collections.emptyList()之间,以及
Set.of()
Collections.emptySet()
之间有什么区别吗?

是的,在
collections
类中的
emptyXyz
工厂方法返回的集合与使用JDK 9的接口(
Map
List
Set
)中引入的新
工厂方法之间甚至存在行为上的差异,而不仅仅是技术上的差异,如果调用这些函数时没有参数

相关的区别在于,新的
of
工厂方法返回的集合不允许
null
键和值(如、和接口中的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中实现的那样,新工厂方法返回的集合上至少有以下方法将抛出
NullPointerException
s,但行为“正常”(就像最初设计和指定集合类以支持null键和值的方式一样)使用
集合
类中的旧factory方法:

  • List.of().contains(null)
  • Set.of().contains(null)
  • Map.of().containsKey(空)
  • Map.of().containsValue(null)
  • Map.of().getOrDefault(null,)

您希望看到什么样的差异?方法名称不同,但结果数据结构的行为极为相似。@C-Otto如果您声称这些方法只是“极为相似”(而不是完全相同),你肯定认为这是有区别的。@jarnbjo有区别-看我的answer@xenteros这个问题足够有效,并且返回的对象中存在相关的差异,不仅是特定的类(正如您在回答中指出的),还包括类的实现和行为方式。我只是不明白C-Otto所说的“OP想要什么样的区别”有什么意义。是的,返回的对象之间存在差异,这些差异的列表可能是一个答案,尽管我自己不是100%确定这些差异是否只是实现特定的,或者可能是OpenJDK 9当前状态下的bug。另请参见:+1这很好。也许,当您注意到“正如API文档中指出的那样”时,请在所有集合类型中指定“不可变静态工厂方法”部分,其中解释了这些实例的属性。@slim这里没有向后兼容性问题。
X.of()。现有代码将继续在旧Java版本中工作。@Jesper值得指出的是,如果不希望行为发生变化,就不能进入旧代码并将
Collections.emptySet()
全局替换为
Set.of()
。特别是有几个人(包括我)错误地给出了一个答案,建议你可以这样做。这种行为并不是“新的”。Map和Set是接口。接口允许不同的实现。一些实现支持空值,其他实现不支持空值。例如,ConcurrentSkipListMap还会在
containsKey(null)
上抛出NPE。接口文档也这么说。@8472井是的;但即使是jdk开发人员也发现了支持Null的集合,弥补了早期实现的不足。