2 回答

TA贡献1772条经验 获得超8个赞
考虑以下示例:
List<String> people
= getPeople().stream()
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
对于这个例子,我使用的是Collections::unmodifiableList方法,所以让我们检查源代码:
/**
* Returns an unmodifiable view of the specified list. This method allows
* modules to provide users with "read-only" access to internal
* lists. Query operations on the returned list "read through" to the
* specified list, and attempts to modify the returned list, whether
* direct or via its iterator, result in an
* <tt>UnsupportedOperationException</tt>.<p>
*
* The returned list will be serializable if the specified list
* is serializable. Similarly, the returned list will implement
* {@link RandomAccess} if the specified list does.
*
* @param list the list for which an unmodifiable view is to be returned.
* @return an unmodifiable view of the specified list.
*/
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
正如@Pshemo 在评论中提到的那样,它UnmodifiableList可以作为列表的包装器,您还可以在源代码中检查该类包含一个列表:
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
implements List<E> {
private static final long serialVersionUID = -283967356065247728L;
final List<? extends E> list; // Here is the wrapped list
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
...
}
可以在此处找到用于提取这些代码的源代码。
所以回答你的问题:
流使用方法等Collections::unmodifiableList方法创建不可变列表
内部流不会在不同的列表中添加任何内容,因为它ImmutableList只是作为包装器工作Collection
您还可以查看文档和来源,以了解这些不可变相关方法和对象的工作原理。

TA贡献1830条经验 获得超3个赞
任何实现都会以某种方式将元素累积到具有某种程度的可变性的结构中,然后返回一个无法修改的列表。
如何完成的细节取决于实现,但这里有几种可能性:
元素被累积到一个
ArrayList
中,然后被复制到一个不可变列表中。元素被累积到一个
ArrayList
中,并返回一个防止修改的包装器(例如Collections.unmodifiableList
。)由于没有其他对象引用原始ArrayList
的 ,因此结果是不可变的。这些元素被累积到一些技术上不是列表的结构中,例如原始数组,并且该数组被复制或包装在不可变的列表对象中。
选择这些实现中的哪一个取决于Collector
您调用的特定对象,例如Collectors.toList()
或ImmutableList.toImmutableList()
。该实现的细节取决于该库的作者,他们可以使用任何这些策略。
添加回答
举报