Java 使用流从现有列表创建不可变列表
有一个Java 使用流从现有列表创建不可变列表,java,collections,java-8,java-stream,collectors,Java,Collections,Java 8,Java Stream,Collectors,有一个Person对象列表 List persons=generatePersons() 将使用它创建一个不可修改的列表 List unmodifiableList=Collections.unmodifiableList(个人) 我知道unmodifiableList不支持添加/删除/设置操作。同时,它也不是不可变的,因为它引用了一个现有的可修改列表人员,每当对人员列表进行更改时,这些更改也会反映在不可修改列表中 这样就创建了一个不可变列表 List immutableList=Collect
Person
对象列表
List persons=generatePersons()代码>
将使用它创建一个不可修改的列表
List unmodifiableList=Collections.unmodifiableList(个人)代码>
我知道unmodifiableList
不支持添加/删除/设置操作。同时,它也不是不可变的,因为它引用了一个现有的可修改列表人员
,每当对人员
列表进行更改时,这些更改也会反映在不可修改列表
中
这样就创建了一个不可变列表
List immutableList=Collections.unmodifiableList(新ArrayList(persons))代码>
这将创建一个不可变列表,因为正在使用转换构造函数。不能对immutableList
执行添加/删除/设置操作,也不能在immutableList
中反映原始列表人员的任何更改。
让我们假设Person
对象也是不可变的
现在,我想使用streams创建这两个列表
第一个,我使用以下方法创建:
List unmodifiablePersons=persons.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),Collections::unmodifiableList))代码>
我在通过流创建等价于immutableList的东西时迷失了方向
我该怎么做
编辑:
我向原始列表添加了一个新的Person
对象persons
,并打印了persons
列表和不可修改的persons
的大小。两个给我的尺码都一样。
因此,变化被反映到不可修改的人身上,因此它还不是一成不变的。我是不是遗漏了什么
编辑2
傻。应该检查一下文件<代码>不可修改的人
确实是一个不可更改的列表。此外,新的Person
对象是在创建不可修改的Person
之前添加的,因此上述观察结果是正确的。太傻了 在第一种情况下,有人可以访问列表不可修改列表
并对其进行编辑,但当您收集
时,没有人可以访问由收集器生成的列表。toList
-所以您很好
您可能缺少的是Collectors::toList
将创建一个新的列表,这应该是显而易见的;你把它包装成一个不可修改的,因此结果是不可修改的
java-10中也有专门的收集器:
List<Integer> result = Arrays.asList(1, 2, 3, 4)
.stream()
.collect(Collectors.toUnmodifiableList());
List result=Arrays.asList(1,2,3,4)
.stream()
.collect(Collectors.toUnmodifiableList());
此收集器使用java-9中添加的内部不可变集合,例如,它们不支持空值 使用Java10+,您可以使用内置功能创建不可修改的列表,如下所示:
List<Person> persons = generatePersons();
List<Person> unmodifiableList = List.copyOf(persons);
List persons=generatePersons();
列表不可修改列表=列表。副本(人);
此外,您正在使用的当前列表实际上也是不可变的,如文档中所述。您的示例是一个不可变列表。事实上,这就是医生们给出的例子:@zron我已经用我的观察更新了我的问题。请仔细查看。@Sara你不是-这确实是一个视图,它是列表
建议在JDK邮件列表上查看的,而复制
方法是与收集器一起实现的,以收集到设置,列表和映射。@zron用edit2更新。我很失望他们没有从toList()
中删除可变性歧义。不可变列表和可能不可变列表之间没有太大的实际区别。@shmosel你是说从收集器::toList
的文档中?@shmosel删除它可能意味着他们必须坚持可变或不可变,我想。Stuart Marks的评论说,他们认为Collectors::toList
终究会在未来返回一个不可变的列表,但现在有了toUnmodifiableList()
@shmosel right,这将是毫无意义的,现在我想知道为什么不明确指定toList
是可修改的,你不能,因为文档已经存在了。使我想起Optional::get
和Optional::orelsetrow
(无参数)