17

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

Collections.unmodifiableList(strings)

或切换到:

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

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

4

2 回答 2

17

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

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

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

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

但是正确性胜过性能。你需要什么?如果您需要不可变副本,请使用新方法(或 Guava 的Immutable...,我更喜欢)。如果您需要不可变的东西,请使用unmodifiable...并丢弃原始文件(并确保它保持原样)。如果您需要调用者无法编辑的视图,请使用unmodifiable....

于 2016-09-08T15:45:37.677 回答
5

根据JEP 269(集合的便利工厂方法)

目标

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

非目标

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

  • 支持具有任意数量元素的高性能、可扩展的集合不是目标。重点是小型收藏。

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

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

于 2016-09-08T08:27:16.990 回答