就 space 效率而言,使对象列表不可变的最佳方法是什么?

What is the best way in terms of space efficiency to make a List of objects immutable?

37:19 of this talk by Stuart Marks on Java Collections 提供的示例的提示下,我想知道从 space 效率的角度来看,使对象列表不可变的最佳方法是什么。

在我的示例中,我有一个从数据库中检索的对象列表:

List<MyObject> myObjects = myRepository.getMyObjectsThatFitCriteria();

为了使这个列表不可变,我可以想到三种方法

  1. 将其包装在 Collections.unModifiableList() 中,但这会创建另一个对象,并且底层列表本身仍然可以修改
  2. 流过 myObjects 列表并将其收集到不可修改的列表中,但这可能会对性能产生影响,尤其是当列表很大时
  3. 使用 Java 9 中引入的 List.copyOf() 静态工厂方法,但这会创建 myObjects 列表的另一个副本,影响内存和存储。

正如@VGR 在评论中提到的,Collections.unmodifiableList 不会将元素复制到新列表中,而是将其包装起来并防止对其进行修改。

如果您使用 Spring Data JPA 来支持存储库,最好利用它对流的支持:https://www.baeldung.com/spring-data-java-8

如果列表很大,流是避免大量内存消耗的好方法。不改变源集合,允许惰性消费

Wrap it in Collections.unModifiableList() but this creates another object and the underlying list itself is still modifiable.

您仍然需要创建一个列表,所以没有办法解决这个问题。但是您始终可以重新分配给同一个列表,以有效地从访问中删除引用。

list = Collections.unModifiableList(list);

对于像 size() 这样的不可变方法,内部的原始列表只是简单地引用(因此不会复制)。任何其他允许更改的方法都会被调用时抛出异常的方法覆盖。所以开销很小。

请注意,除非包含的对象是不可变的,否则它们仍然可以更改。