Collectors.toList() 和 Stream.toList() 这两种方法的区别是什么
在 Java 中,stream().collect(Collectors.toList()) 和 stream().toList() 都是将 Stream 转换为 List 的方法,但它们在 实现方式、性能、可变性 等方面有显著区别。以下是详细对比:
1. stream().collect(Collectors.toList())
List<String> collect = a.stream().collect(Collectors.toList());
特点:
- 返回的
List类型:- 具体实现取决于 JDK 版本:
- JDK 8~15:返回
ArrayList(默认)。 - JDK 16+:可能返回不可变
List(取决于Collectors.toList()的实现优化)。
- JDK 8~15:返回
- 但 官方未明确保证返回类型,理论上可能是任意
List实现。
- 具体实现取决于 JDK 版本:
- 可变性:
- 返回的
List通常是可变的(如ArrayList),可以调用add()、remove()等方法。 - 但如果 JDK 内部优化(如 JDK 16+ 的某些情况),可能返回不可变
List。
- 返回的
- 性能:
- 需要额外创建
Collectors.toList()收集器对象,会有轻微性能开销。 - 底层仍然是调用
Stream的收集逻辑,与toList()差异不大。
- 需要额外创建
- 线程安全:
- 返回的
List不是线程安全的(除非显式包装为Collections.synchronizedList)。
- 返回的
2. stream().toList()
List<String> strings = a.stream().toList();
特点:
- 返回的
List类型:- JDK 16+ 明确保证:返回一个不可变
List(具体实现可能是List.of()或内部优化类)。 - 如果流为空,返回一个空的不可变
List(而非null)。
- JDK 16+ 明确保证:返回一个不可变
- 可变性:
- 返回的
List严格不可变,调用add()、remove()会抛出UnsupportedOperationException。
- 返回的
- 性能:
- 比
Collectors.toList()更高效,因为:- 直接内联到 Stream API 的实现中,无需额外收集器对象。
- 针对不可变性做了优化(如共享数据、延迟拷贝)。
- 比
- 线程安全:
- 不可变
List本质是线程安全的(只要不尝试修改)。
- 不可变
3. 核心区别总结
代码示例
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class StreamToListComparison { public static void main(String[] args) { // 源列表 List<String> sourceList = List.of("apple", "banana", "cherry"); // 使用 Collectors.toList() List<String> mutableList = sourceList.stream() .collect(Collectors.toList()); System.out.println("Mutable List: " + mutableList); // 尝试修改可变列表 mutableList.add("date"); System.out.println("After adding to mutable list: " + mutableList); // 使用 Stream.toList() List<String> immutableList = sourceList.stream() .toList(); System.out.println("Immutable List: " + immutableList); // 尝试修改不可变列表(会抛出异常) try { immutableList.add("elderberry"); } catch (UnsupportedOperationException e) { System.out.println("Exception caught: " + e.getMessage()); } // 处理空流的情况 List<String> emptyMutableList = new ArrayList<>().stream() .collect(Collectors.toList()); System.out.println("Empty mutable list size: " + emptyMutableList.size()); List<String> emptyImmutableList = new ArrayList<>().stream() .toList(); System.out.println("Empty immutable list size: " + emptyImmutableList.size()); } }
输出结果
Mutable List: [apple, banana, cherry] After adding to mutable list: [apple, banana, cherry, date] Immutable List: [apple, banana, cherry] Exception caught: Unsupported operation Empty mutable list size: 0 Empty immutable list size: 0

浙公网安备 33010602011771号