由于没有元素可以添加到不可变列表中,因此我认为java流首先将元素收集到列表中,然后使用第一个列表中的元素创建一个新的不可变列表。因此,该列表有两个实例,第一个实例可用于垃圾回收。
所以我的问题是
答案 0 :(得分:4)
任何实现都将以某种方式将元素累积到具有某种可变性的结构中,然后返回无法修改的列表。
具体操作方法取决于实施,但这有几种可能性:
ArrayList
中,然后被复制到不可变列表中。ArrayList
中,并返回防止修改的包装器(例如Collections.unmodifiableList
。)由于没有其他对象引用原始ArrayList
,因此结果是变得一成不变。选择哪种实现取决于您调用的特定Collector
,例如Collectors.toList()
或ImmutableList.toImmutableList()
。该实现的细节取决于该库的作者,他们可以使用任何这些策略。
答案 1 :(得分:2)
考虑以下示例:
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
用作列表的包装器,您还可以在源代码中检查此类包含内部列表的源: / p>
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;
}
...
}
用于提取这些代码的源代码可以为found here。
所以回答您的问题:
Collections::unmodifiableList
方法之类的方法创建不可变列表ImmutableList
仅用作Collection
的包装您还可以签入文档和资源以了解这些不可变的相关方法和对象的工作原理。