List.of(...) 或 Collections.unmodifiableList()

List.of(...) or Collections.unmodifiableList()

如果你有一个List<String> strings实例,你会继续写:

Collections.unmodifiableList(strings)

或切换到:

List.of(strings.toArray(new String[strings.size()]))

实例化对性能(内存和运行时方面)的初始影响是什么? List.of 变体有运行时优势吗?

根据JEP 269 (Convenience Factory Methods for Collections)

Goals

Provide static factory methods on the collection interfaces that will create compact, unmodifiable collection instances. The API is deliberately kept minimal.

Non-Goals

  • It is not a goal to provide a fully-general "collection builder" facility that, for example, lets the user control the collection implementation or various characteristics such as mutability, expected size, loading factor, concurrency level, and so forth.

  • It is not a goal to support high-performance, scalable collections with arbitrary numbers of elements. The focus is on small collections.

  • It is not a goal to provide unmodifiable collection types. That is, this proposal does not expose the characteristic of unmodifiability in the type system, even though the proposed implementations are actually unmodifiable.

  • It is not a goal to provide "immutable persistent" or "functional" collections.

这不是一个很好的比较,因为这些方法做不同的事情:

  • Collections::unmodifiable... 创建一个不可修改的视图。它不是不可变的,因为如果您更改原始的后备集合(在您的示例中为list),它会发生变化。
  • 另一方面,
  • ...::of 创建一个不可变副本。改变原来的列表不会影响。

从性能的角度来看,显然创建不可修改的包装器成本更低,因为它只创建一个具有单个字段的实例。新的工厂方法将创建至少一个对象,可能由数组支持(如果您有三个或更多元素),它需要复制到其中。

新的不可变集合的访问速度可能会更快,但这必须进行基准测试。

但正确性胜过性能。您需要什么?如果您需要不可变的 copy,请使用新方法(或我更喜欢 Guava 的 Immutable...)。如果你需要 something 不可变,使用 unmodifiable... 并扔掉原来的(并确保它保持那样)。如果您需要调用者无法编辑的视图,请使用 unmodifiable....