使用流从现有列表创建不可变列表

时间:2018-10-26 17:08:44

标签: java collections java-8 java-stream collectors

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对象,因此可以进行上面的观察。超级傻。

2 个答案:

答案 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创建的当前列表实际上也是不可变的,如文档中所述。