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()
。該實現的細節取決于該庫的作者,他們可以使用任何這些策略。
添加回答
舉報