使用流从现有列表创建不可变列表 [英] Creating an immutable list from an existing list using streams
问题描述
有一个Person
对象的列表.
List<Person> persons = generatePersons();
使用它创建一个不可修改的列表.
An unmodifiableList is created with it.
List<Person> unmodifiableList = Collections.unmodifiableList(persons);
我了解unmodifiableList
不支持添加/删除/设置操作.同时,它不是不变的,因为它引用了现有的可修改列表persons
,并且每当对persons
列表进行更改时,这些更改也会反映在unmodifiableList
中.
I understand that unmodifiableList
doesn't support add/remove/set operations. At the same time it is not immutable since it has a reference to an existing modifiable list persons
and whenever changes are made to the persons
list, the changes are reflected in unmodifiableList
too.
以这种方式创建了一个不可变的列表.
An immutable list is created this way.
List<Person> immutableList = Collections.unmodifiableList(new ArrayList<>(persons));
由于使用了转换构造函数,因此创建了一个不可变的列表.不能在immutableList
上执行添加/删除/设置操作,原始列表persons
中的任何更改都不会反映在immutableList
中.
让我们假设Person
对象也是不可变的.
This creates an immutable list since a conversion constructor is being used. No add/remove/set ops can be performed on immutableList
nor any change in the original list persons
would reflect in immutableList
.
Let's make an assumption that Person
objects are immutable too.
现在,我想使用流创建这两个列表.
Now, I want to create these two lists using streams.
第一个,我使用以下方法创建:
The first one, I have created using:
List<Person> unmodifiablePersons = persons.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
List<Person> unmodifiablePersons = persons.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
我迷失于通过流创建等效的immutableList.
I am lost at creating equivalent of immutableList through streams.
我该怎么做?
我在原始列表persons
中添加了一个新的Person
对象,并打印了persons
列表和unmodifiablePersons
的大小.两者都给我相同的尺寸.
因此,更改正在反映到unmodifiablePersons
,因此它还不是一成不变的.我在这里想念东西吗?
I added a new Person
object to the original list persons
and printed the size of persons
list and unmodifiablePersons
. Both give me the same size.
So, changes are being reflected to unmodifiablePersons
and hence it is not immutable yet. Am I missing something here?
编辑2
傻.应该已经通过了文档. unmodifiablePersons
确实是一个不可变的列表.同样,在创建unmodifiablePersons
之前添加了新的Person
对象,因此可以进行上述观察.超级傻.
Silly. Should have gone through the docs. unmodifiablePersons
is indeed an immutable list. Also, the new Person
object was added before the unmodifiablePersons
was created and hence the above observation. Super silly.
推荐答案
在您的第一种情况下,某人可以访问List<Person> unmodifiableList
并可以对其进行编辑,但是当您collect
时,没有人可以访问访问由Collectors.toList
生成的List
-所以您很好.
Well in your first case someone has access to List<Person> unmodifiableList
and can edit it, but when you collect
no one has access to that List
generated by Collectors.toList
- so you are good.
您可能缺少的是Collectors::toList
将创建一个 new 列表-这应该很明显;并且将其包装为不可修改的文件,因此其结果是真正不可修改的.
What you are probably missing is that Collectors::toList
will create a new List - which should really be obvious; and you wrap it into an unmodifiable one, thus the result of that is truly unmodifiable.
在Java-10中,还有一个特殊的收集器:
Also in java-10 there is special collector for that:
List<Integer> result = Arrays.asList(1, 2, 3, 4)
.stream()
.collect(Collectors.toUnmodifiableList());
此收集器内部使用List::of
-java-9中添加的不可变集合,因此,例如,它们不支持null.
This collector uses List::of
internally - immutable collections added in java-9, thus for example they don't support nulls.
这篇关于使用流从现有列表创建不可变列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!