使用Collectors.toList()可转为可变ArrayList,Collectors.toSet()生成无序HashSet并自动去重;需注意线程安全、null处理及顺序要求,可通过toCollection指定LinkedHashSet、TreeSet等定制集合。

用 collect 将流转成 List 或 Set 很简单,关键是选对收集器(Collector)并理解背后的线程安全与重复逻辑。
用 Collectors.toList() 转为 ArrayList
这是最常用的方式,返回的是 ArrayList 实例(非不可变),支持后续增删改。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // → ["ALICE", "BOB", "CHARLIE"]
- 注意:它不保证线程安全,多线程并行流中使用需确认业务无并发修改风险
- 如果需要不可变 List,可在外层套
java.util.List.copyOf(...)(Java 10+)或Arrays.asList(...)+Collections.unmodifiableList
用 Collectors.toSet() 转为 HashSet
自动去重,底层用的是 HashSet,不保证插入顺序,也不保证线程安全。
示例:
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3);
Set<Integer> unique = numbers.stream()
.collect(Collectors.toSet()); // → 可能是 [1, 2, 3](顺序不定)
- 重复元素会被自动丢弃,适合清洗数据场景
- 若需保持插入顺序,改用
Collectors.toCollection(LinkedHashSet::new) - 若需线程安全的 Set,可用
Collectors.toCollection(() -> Collections.synchronizedSet(new HashSet())),但更推荐在收集后加锁或用并发集合处理
自定义集合类型:用 toCollection 指定具体实现类
当默认的 ArrayList 或 HashSet 不满足需求时,可直接指定构造方式。
- 转为
LinkedList:.collect(Collectors.toCollection(LinkedList::new)) - 转为
TreeSet(自然排序):.collect(Collectors.toCollection(TreeSet::new)) - 转为按插入顺序去重的
LinkedHashSet:.collect(Collectors.toCollection(LinkedHashSet::new))
这种方式灵活,且能精准控制集合行为,比如排序、顺序、性能特征等。
小心 null 和空流的边界情况
collect 本身不会因流为空而报错,返回的是空集合;但如果元素含 null,部分集合会抛异常。
-
HashSet、TreeSet不允许null元素,流中若有null会触发NullPointerException -
ArrayList和LinkedList允许null,但要注意业务逻辑是否容错 - 建议提前过滤:
.filter(Objects::nonNull)或做空值映射处理


















