在Java17之前如果需要将Stream流中的元素转换成List,需要通过调用Collectors方法使用Collectors.toList(),代码非常冗长。

在Java17之前使用如下:

List<Integer> integerList = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toList());

Stream.toList()的使用

在Java 17中将会变得简单,可以直接调用Stream.toList()。

List<Integer> integerList1 = Stream.of(1, 2, 3, 4, 5).toList();

Stream.toList()与Collectors.toList()的区别

先来看下Collectors.toList()的源码:

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

在源码里能看到使用Collectors.toList()收集出来的list实际类是ArrayList。

再来看下Stream.toList()的源码:

default List<T> toList() {
    return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));
}

java.util.Collections#unmodifiableList

public static <T> List<T> unmodifiableList(List<? extends T> list) {
    if (list.getClass() == UnmodifiableList.class || list.getClass() == UnmodifiableRandomAccessList.class) {
       return (List<T>) list;
    }

    return (list instanceof RandomAccess ?
            new UnmodifiableRandomAccessList<>(list) :
            new UnmodifiableList<>(list));
}

但是Stream.toList()收集出来的list实际类是UnmodifiableList这个类。

UnmodifiableList介绍

UnmodifiableList是Java中的一个类,用于创建不可修改的列表。它实际上是通过Collections.unmodifiableList()方法创建的。一旦列表被创建为不可修改的,就无法对其进行添加、删除或修改元素的操作。这种列表对于保护数据不被意外修改或者共享数据而不希望被修改很有用。当你想要确保某个列表在传递给其他代码时不会被修改时,可以使用UnmodifiableList来包装你的列表。

从UnmodifiableList的源码可以看出,对UnmodifiableList中元素的增删改操作都会抛出UnsupportedOperationException异常。

public E set(int index, E element) {
    throw new UnsupportedOperationException();
}

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

public E remove(int index) {
    throw new UnsupportedOperationException();
}

public boolean addAll(int index, Collection<? extends E> c) {
    throw new UnsupportedOperationException();
}

@Override
public void replaceAll(UnaryOperator<E> operator) {
    throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
    throw new UnsupportedOperationException();
}

结论:如果你想在stream后对list进行修改操作,那么就用Collectors.toList(),如果不想结果被修改操作,那么就直接使用Stream.toList()。