ToList()的实现清楚地返回了一个ArrayList,它保证了可变性:

public static <T>
Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>(ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}

但toList的JavaDoc读作:

/**
 * Returns a {@code Collector} that accumulates the input elements into a
 * new {@code List}. There are no guarantees on the type, mutability,
 * serializability, or thread-safety of the {@code List} returned; if more
 * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
 *
 * @param <T> the type of the input elements
 * @return a {@code Collector} which collects all the input elements into a
 * {@code List}, in encounter order
 */

为什么不能保证可变性?我是否遗漏了返回的集合可能是不可变的情况?当返回的集合需要可变性时,使用Collectors.toList()是否安全?

推荐答案

因为作者这么说

为什么不能保证可变性?

因为Collectors.toList方法的设计者 Select 了这样的方法.

ToList()的实现清楚地返回一个ArrayList

这一事实只是一个实施细节.

该细节仅适用于您研究的一个实现的一个版本.其他版本和其他实现可能使用ArrayList以外的值.

在文件promise 的合同范围内,任何实施均可更改.重要的是该文档promise 的行为.

引用贾瓦多克的话:

返回Collector,将输入元素累加到新的List中.不能保证返回的List的类型、可变性、可序列化或线程安全性;如果需要对返回列表进行更多控制,请使用toCollection(Supplier).

在我看来非常清楚.您已经得到promise ,得到的List可能是可变的,也可能是不可变的.你已经被告知不要依赖任何一种情况.

可修改

如果您想要一个可变/可修改的List,👉🏽可以从您的收集器生成的列表中创建一个新的.将收集的列表传递给新列表对象的构造函数.

List< Whatever > list = new ArrayList<>( collectorList ) ;

或者,正如上面的Java代码所建议的,您可以使用👉🏽PassSupplier来呈现您 Select 的列表实现.拨打Collectors.toCollection.参见Baeldung.com上的section 3.3教程.

例如:

toCollection( ArrayList :: new )

不可更改

如果您想要一个不变的/unmodifiable列表,我建议👉🏽呼叫List.copyOf.

List< Whatever > list = List.copyOf( collectorList ) ;

这种方法promise 会有回报:

…一个不可修改的列表,包含给定Collection的元素,按其迭代顺序排列.

但是有一个问题:不允许空值.有两个空值列表的替代方案:


顺便说一句,Java 21带来了sequenced collections.因此,List更通用的接口是SequencedCollection.

SequencedCollection< Whatever > sequence = List.copyOf( collectorList ) ;

Java相关问答推荐

如何使用解析器组合子解析Java数组类型签名?

在AnyLogic中增加变量计数

为什么我们仍然需要实现noArgsConstructor如果Java默认提供一个非参数化的构造函数?''

替换com. sun. jndi. dns. DnsContextFactory Wildfly23 JDK 17

Java inline Double条件和值解装箱崩溃

对某一Hyroby控制器禁用@cacheable

如何才能使我的程序不会要求两次输入?

是否在允许数组元素为空时阻止 idea 为空性警告?

我可以在MacOS上使用什么Java函数来在适当的设备上以适当的音量播放适当的alert 声音?

Spring安全令牌刷新和JWT签名与本地计算的签名不匹配

无法使用Java PreparedStatement在SQLite中的日期之间获取结果

为了安全起见,有必要复制一份 list 吗?

Java 17与Java 8双重表示法

为什么Instant没有从UTC转换为PostgreSQL的时区?

由于版本不匹配,从Java 8迁移到Java 17和Spring 6 JUnit4失败

当我try 返回可选时,Mock无法正常工作

在JSON上获取反斜杠

";重复键的值提示唯一约束«;livre_genre_pkey»";例外

java中的网上购物车解析错误

将天数添加到ZonedDateTime不会更改时间