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

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

 Collections.unmodifiableList(strings) 

或切换到:

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

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

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

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

从性能视图可以看出,不可修改的包装器的创建更便宜,因为它只创建一个具有单个字段的实例。 新的工厂方法将创建至少一个对象,可能由数组支持(如果您有三个或更多元素),它需要复制到该对象中。

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

但正确性胜过表现。 你需要什么? 如果您需要一个不可变的副本 ,请使用新方法(或者我更喜欢的Guava的Immutable... )。 如果你需要一些不可变的东西 ,可以使用unmodifiable...然后扔掉原来的(并确保它保持原样)。 如果您需要调用者无法编辑的视图,请使用unmodifiable...

根据JEP 269(便利工厂收集方法) :

目标

在集合接口上提供静态工厂方法,这些方法将创建紧凑的,不可修改的集合实例。 API故意保持最小化。

非目标

  • 提供完全通用的“集合构建器”设施并不是一个目标,例如,它允许用户控制集合实现或各种特性,例如可变性,预期大小,加载因子,并发级别等。

  • 支持具有任意数量元素的高性能,可伸缩集合并非目标。 重点是小集合。

  • 提供不可修改的集合类型不是目标。 也就是说,即使提议的实现实际上是不可修改的,该提议也没有暴露类型系统中的不可修改性的特征。

  • 提供“不可变持久性”或“function性”集合不是目标。