就 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();
为了使这个列表不可变,我可以想到三种方法
- 将其包装在
Collections.unModifiableList()
中,但这会创建另一个对象,并且底层列表本身仍然可以修改
- 流过
myObjects
列表并将其收集到不可修改的列表中,但这可能会对性能产生影响,尤其是当列表很大时
- 使用 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()
这样的不可变方法,内部的原始列表只是简单地引用(因此不会复制)。任何其他允许更改的方法都会被调用时抛出异常的方法覆盖。所以开销很小。
请注意,除非包含的对象是不可变的,否则它们仍然可以更改。
在 37:19 of this talk by Stuart Marks on Java Collections 提供的示例的提示下,我想知道从 space 效率的角度来看,使对象列表不可变的最佳方法是什么。
在我的示例中,我有一个从数据库中检索的对象列表:
List<MyObject> myObjects = myRepository.getMyObjectsThatFitCriteria();
为了使这个列表不可变,我可以想到三种方法
- 将其包装在
Collections.unModifiableList()
中,但这会创建另一个对象,并且底层列表本身仍然可以修改 - 流过
myObjects
列表并将其收集到不可修改的列表中,但这可能会对性能产生影响,尤其是当列表很大时 - 使用 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()
这样的不可变方法,内部的原始列表只是简单地引用(因此不会复制)。任何其他允许更改的方法都会被调用时抛出异常的方法覆盖。所以开销很小。
请注意,除非包含的对象是不可变的,否则它们仍然可以更改。