有Person
个对象的列表。
List<Person> persons = generatePersons();
创建一个不可修改的列表。
List<Person> unmodifiableList = Collections.unmodifiableList(persons);
我了解到unmodifiableList
不支持添加/删除/设置操作。同时,它不是不变的,因为它引用了现有的可修改列表persons
,并且每当对persons
列表进行更改时,这些更改也会反映在unmodifiableList
中。
以这种方式创建不可变列表。
List<Person> immutableList = Collections.unmodifiableList(new ArrayList<>(persons));
由于使用了转换构造函数,因此创建了一个不可变列表。无法在immutableList
上执行添加/删除/设置操作,对原始列表persons
的任何更改都将反映在immutableList
中。
让我们假设Person
对象也是不可变的。
现在,我想使用流创建这两个列表。
第一个,我使用以下方法创建:
List<Person> unmodifiablePersons = persons.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
我迷失于通过流创建等效的immutableList。
我该怎么做?
修改:
我在原始列表Person
中添加了一个新的persons
对象,并打印了persons
列表和unmodifiablePersons
的大小。两者都给我相同的尺寸。
因此,更改正在反映到unmodifiablePersons
上,因此它还不是一成不变的。我在这里想念东西吗?
编辑2
傻。应该已经通过了文档。 unmodifiablePersons
确实是一个不变的列表。同样,在创建Person
之前添加了新的unmodifiablePersons
对象,因此可以进行上面的观察。超级傻。
答案 0 :(得分:8)
在您的第一种情况下,某人可以访问List<Person> unmodifiableList
并可以对其进行编辑,但是当您collect
时,没有人可以访问由List
生成的Collectors.toList
Collectors::toList
-很好。
您可能缺少的是List<Integer> result = Arrays.asList(1, 2, 3, 4)
.stream()
.collect(Collectors.toUnmodifiableList());
将创建一个 new 列表-这应该很明显;并且将其包装为不可修改的文件,因此其结果是真正不可修改的。
在Java-10中,还有一个特殊的收集器:
List::of
此收集器在内部使用wscanf
-java-9中添加的不可变集合,因此,例如,它们不支持null。
答案 1 :(得分:4)
使用Java10 +,您可以使用内置功能copyOf
来创建不可修改的列表,如下所示:
List<Person> persons = generatePersons();
List<Person> unmodifiableList = List.copyOf(persons);
此外,您使用Collector.collectingAndThen
创建的当前列表实际上也是不可变的,如文档中所述。