List.of()或Collections.emptyList()

Sor*_*ras 17 java collections java-9

作为List.of(...)或Collections.unmodifiableList()的一个特例- 指向空的不可变列表的首选Java 9方式是什么?

继续写

Collections.emptyList();
Run Code Online (Sandbox Code Playgroud)

或切换到

List.of();
Run Code Online (Sandbox Code Playgroud)

chr*_*ke- 15

Collections.emptyList()不需要为每个调用创建一个新对象; 像在OpenJDK中一样,返回单例EMPTY_LIST对象是典型的.此外,更清楚的是,您打算表示一个空列表,而不是忘记填写占位符.

使用emptyList(); 它更快(达到Java目标级别1.9)并且更具可读性.

  • @Sormuras ...集合工厂都共享一个通用的串行格式(序列化代理),如果我们希望将来更容易更改内部结构.另外,调用mutator方法时,`emptyList()`的行为略微松懈.例如,`emptyList().addAll(emptyList())`是一个无操作,但是`List.of().addAll(emptyList())`抛出`UnsupportedOperationException`. (8认同)
  • 我已经修复[JDK-8156079(https://bugs.openjdk.java.net/browse/JDK-8156079),以便在JDK 9月初访问构建144及更高版本,`List.of()`,`设置.of()`和`Map.of()`使用单例作为空实例. (8认同)
  • @Andreas没有内在的原因`List.of()`每次都不能返回相同的实例.它尚未实施.参见[JDK-8156079](https://bugs.openjdk.java.net/browse/JDK-8156079).也就是说,权衡并不总是显而易见的.使用缓存实例可能会整体节省内存,但它也会阻止JIT进行某些优化.这肯定发生在自动装箱缓存上.`List.of()`不调用`Collections.emptyList()`的原因是后者有一个明确定义的串行形式,由于兼容性原因无法更改.新的... (7认同)
  • `emptyList()`并不是更快,并且`List.of()`“也不需要为每个调用创建一个新对象”。答案已经过时了。 (3认同)
  • @Andreas实际上,没关系; 它仍在创建一个新的空占位符. (2认同)
  • 它是,但你可能想知道*为什么*`List.of()`不只是调用`Collections.emptyList()`.我没有看过那里是否有任何讨论,但我想这是为了确保你总是得到一个*new*列表,对于单独实例很重要的情况.所以,你新的实例很重要,使用`List.of()`.如果你不在乎,可以使用`Collections.emptyList()`,这也更好地描述了目的,正如你已经说过的那样. (2认同)
  • @Andreas因为它们都是不变的,所以我想不出任何可能重要的情况; API要求空列表为"equals",理论上只有一个不同的实例. (2认同)

use*_*551 14

指向空且不可变列表的首选 Java 9 方式是什么?

差异相当微妙,因此“首选”取决于您想要实现的目标。一些行为差异:

  • List.ofcontains(null)调用时会抛出异常。
  • 您可以emptyList()在 JDK 8 及更早版本上反序列化,但不能在List.of.

就或表达您想要一个空列表而言,emptyList()可能看起来更好,但这只是一个临时约定。如果开发人员开始使用List.of()(比 短得多Collections.emptyList()),那么它将成为一种已知和接受的方式,它只是新的。如果你考虑一下,我们使用的一些结构并不总是传达它们自己所做的事情,但我们已经习惯了它们。

所以没有严格的首选方式。如果行为无关紧要,请使用您想要的任何内容。

  • @Sormuras:[如明确说明](https://stackoverflow.com/help/accepted-answer):“*接受答案并不意味着是一个明确的最终声明,表明该问题现已得到完美回答*” ……顺便说一下,如果更新的答案更合适或者旧的已经过时,您可以接受它。 (3认同)
  • @Sormuras 我很清楚,所以?人们希望在阅读问题时看到更新的信息。本网站上的问题不会过时,只要有解决问题的新方法,就会更新新答案。 (2认同)

小智 14

从 JDK 11 开始,如果您查看源代码,您会发现List.of(), 使用一次性初始化的空列表,类似于Collections.emptyList(). 所以,我更喜欢使用,List.of()因为:

  • 这是一个更新的 API。所以,我认为如果 Java 维护者对以前的方式感到满意,他们就不会添加新的 API。
  • 它更加简洁。
  • 如果您对非空列表使用List.of(E... elements)并且您应该List.of()),则可以用于空列表并享受统一的外观和感觉,并摆脱Collections API 中的大部分工厂方法。