326. Java Stream API - 实现自定义的 toList() 与 toSet() 收集器

作者:yaoxin521123日期:2026/2/23

文章目录

  • 326. Java Stream API - 实现自定义的 `toList()` 与 `toSet()` 收集器
    • 📦 实现一个自定义 `toList()` 收集器
    • 🚀 使用我们的 `ToList` 收集器
    • 🔄 将其改造成 `toSet()` 收集器
      • ✅ 修改 1:使用 `HashSet` 作为容器
        • ✅ 修改 2:声明该收集器是无序的
    • 🧪 `ToSet` 收集器完整实现示例
    • 🎯 总结一下关键点
    • 🧠 小贴士

326. Java Stream API - 实现自定义的 toList()toSet() 收集器

在 Java 的 Stream API 中,Collectors.toList()Collectors.toSet() 是最常见的两个内置收集器。但你是否好奇它们背后的原理?今天我们就带大家手动实现一个行为等同于 toList() 的收集器,并了解如何基于它改造为 toSet() 收集器。


📦 实现一个自定义 toList() 收集器

1class ToList<T> implements Collector<T, List<T>, List<T>> {
2
3    @Override
4    public Supplier<List<T>> supplier() {
5        return ArrayList::new; // 创建一个空的 ArrayList 作为中间容器
6    }
7
8    @Override
9    public BiConsumer<List<T>, T> accumulator() {
10        return Collection::add; // 将元素累加到 List 
11    }
12
13    @Override
14    public BinaryOperator<List<T>> combiner() {
15        return (list1, list2) -> {
16            list1.addAll(list2); // 合并两个 List(用于并行流)
17            return list1;
18        };
19    }
20
21    @Override
22    public Function<List<T>, List<T>> finisher() {
23        return Function.identity(); // 直接返回中间容器,不需要额外转换
24    }
25
26    @Override
27    public Set<Characteristics> characteristics() {
28        return Set.of(Characteristics.IDENTITY_FINISH); // 说明 finisher  identity
29    }
30}
31

🚀 使用我们的 ToList 收集器

1Collection<String> strings = List.of("one", "two", "three", "four", "five");
2
3List<String> result = strings.stream()
4    .collect(new ToList<>()); // 使用我们自定义的收集器
5
6System.out.println("result = " + result);
7

💡 输出结果:

1result = [one, two, three, four, five]
2

🔄 将其改造成 toSet() 收集器

我们只需要修改两处,就能实现一个等价于 Collectors.toSet() 的收集器:

✅ 修改 1:使用 HashSet 作为容器

1public Supplier<Set<T>> supplier() {
2    return HashSet::new;
3}
4

✅ 修改 2:声明该收集器是无序的

1public Set<Characteristics> characteristics() {
2    return Set.of(
3        Characteristics.IDENTITY_FINISH,
4        Characteristics.UNORDERED // 不保证处理顺序
5    );
6}
7

🧪 ToSet 收集器完整实现示例

1class ToSet<T> implements Collector<T, Set<T>, Set<T>> {
2
3    @Override
4    public Supplier<Set<T>> supplier() {
5        return HashSet::new;
6    }
7
8    @Override
9    public BiConsumer<Set<T>, T> accumulator() {
10        return Set::add;
11    }
12
13    @Override
14    public BinaryOperator<Set<T>> combiner() {
15        return (set1, set2) -> {
16            set1.addAll(set2);
17            return set1;
18        };
19    }
20
21    @Override
22    public Function<Set<T>, Set<T>> finisher() {
23        return Function.identity();
24    }
25
26    @Override
27    public Set<Characteristics> characteristics() {
28        return Set.of(
29            Characteristics.IDENTITY_FINISH,
30            Characteristics.UNORDERED
31        );
32    }
33}
34

🎯 总结一下关键点

元素toList()toSet()
容器类型ArrayListHashSet
是否无序❌(有序)✅(无序)
特性声明IDENTITY_FINISHIDENTITY_FINISH, UNORDERED

🧠 小贴士

  • 想提升性能? 在能接受无序的场景中使用 UNORDERED
  • 想避免不必要的转换?AR 类型一致时,记得声明 IDENTITY_FINISH
  • 并行流支持? 如果想支持并行执行,还可以考虑加入 CONCURRENT 特性(配合线程安全结构)。

326. Java Stream API - 实现自定义的 toList() 与 toSet() 收集器》 是转载文章,点击查看原文


相关推荐


Kafka 生产者与消费者配置详解
倚肆2026/2/15

Kafka 生产者与消费者配置详解 一、DefaultKafkaProducerFactory 生产者配置详解 配置项示例值作用说明调优建议ProducerConfig.BOOTSTRAP_SERVERS_CONFIG"localhost:9092"Kafka 集群地址列表,生产者通过此地址发现集群。配置多个地址(用逗号分隔)以提高可用性。ProducerConfig.KEY_SERIALIZER_CLASS_CONFIGStringSerializer.class消息键的序列化器。键用于分区


Spring IOC&DI(上)
阿武不想上早八2026/2/6

Spring IOC&DI(上) 1. Spring IOC&DI Spring 是包含了众多工具方法的 IOC 容器 1.1 容器 概念:容器时用来容纳物品的装置。 例子:List/Map -> 数据存储容器;Tomcat -> Web 容器 1.2 IOC 概念:全称:Inversion of Control(控制反转),是 Spring 的核心思想,把对象交给 Spring 管理,就是 IOC 思想。 总的来说,Spring 就是一个”控制反转“的容器。 2. I


【学习笔记】C++(1)
贺一航【Niki】2026/1/28

C++学习笔记 一、基础 1、类型表示范围 2、cout 3、char 4、string 5、逻辑运算符 6、枚举 7、随机数 8、数组 9、其他 一、基础 1、类型表示范围 类型 字节数 位宽 十进制范围(大约) 具体值范围 char 1


【AI大模型开发】-基于FAISS的语义搜索系统(实战)
Java后端的Ai之路2026/1/19

向量数据库实战:基于FAISS的语义搜索系统 一、项目概述 1.1 什么是向量数据库? 向量数据库是一种专门用于存储、索引和检索高维向量数据的数据库系统。在AI领域,向量通常是指通过预训练模型(如Transformer)将文本、图像等非结构化数据转换而成的数值表示(Embedding)。 1.2 项目背景 本项目展示了如何使用阿里云百炼Embedding API生成文本向量,并结合FAISS(Facebook AI Similarity Search)构建一个简单但功能完整的语义搜索系统。 1.


Claude Skills:Agent 能力扩展的新范式
清沫2026/1/11

为什么需要 Skills? 2025 年被称为智能体元年。各类 Agent、子 Agent、MCP 工具及自动化流水线迅速出现,让 AI 可以接手越来越多真实工作。比如 Claude Code 推出的 Agent 模块,或通过可视化平台、LangChain 开发的各种工具。 随着智能体功能增强,需要更具可组合性、可扩展性和可移植性的方法,为它们配备特定领域专业知识。这促使智能体 Skills 诞生:智能体可动态发现并加载包含指令、脚本和资源的文件夹,从而更好完成特定任务。 什么是 Skills?


2025年度总结之-如何构建 2025 专属的 GitHub AI 项目情报库
CoderJia_2026/1/3

背景 为什么做 为了更好地追踪 2025 年涌现的 AI 开源项目,我经常浏览 Github 热榜 并整理分享。但手动查阅难免会有遗漏,为此,我计划开发一套自动化工具来采集 Github 热榜数据,旨在辅助个人技术积累的同时,也为博客内容提供持续的素材来源。下文将详细介绍我的技术实现思路,若有设计不足之处,恳请各位读者指正。 如何制作 在该流程的初始阶段,核心任务是构建针对 GitHub 热榜(Trending)页面的数据采集机制。需要分别按照日(Daily)、周(Weekly)及月(M


从字符游戏到 CPU 指令集:一道算法题背后的深度思维跃迁
ToddyBear2025/12/24

"Simplicity is the ultimate sophistication." — Leonardo da Vinci 前言:很多时候,一道看似简单的算法题,不仅是代码能力的试金石,更是计算机底层思维的显微镜。本文记录了一次关于“查找 K-th 字符”问题的深度探讨。我们不满足于“做出来”,而是试图通过逆向工程,从直觉出发,推导出数学原理,最终触达硬件指令集的设计哲学。 🟢 第一部分:面试极速备忘录 (Executive Summary) 为了方便日后快速回顾(如面试前 5


5 分钟快速入门 Gitlab CI/CD
yuguo.im2025/12/16

🚀 快速掌握 GitLab CI/CD:自动化你的开发流程 GitLab CI/CD 是一个功能强大的工具,它内置于 GitLab 中,用于自动化你的软件构建、测试和部署流程。如果你希望提升开发效率、减少人为错误并实现持续集成/持续部署(CI/CD),那么掌握它至关重要。 本文将通过最核心的概念、最简单的配置,带你快速入门 GitLab CI/CD。 核心概念:理解 GitLab CI 的基石 在编写你的第一个配置文件之前,理解以下几个关键概念是掌握 GitLab CI 的前提: 1. 配置


这5个AI文本可视化工具太强了!一键把文本转信息图、流程图等多种可视化形式!PPT秒变高级!(建议收藏)
程序员X小鹿2025/12/8

大家好,我是X小鹿。 前几天被读者问到了「文本可视化」工具,趁着周末,整理了下之前体验过的几款还不错的 AI 工具。 这些 AI 工具都可以一键将枯燥的文本,转化为精美信息图、数据图、卡片等形式。 不管是在项目汇报中插入,还是用于 PPT 配图、文章配图、生成科普图文、读书笔记卡片、自媒体图文创作等场景,都是可以的。 下面分享 5 个目前国内外用得较多「文本可视化」工具。 有需要的可以保存下,早晚用得上~ 一、Seede AI 第一个,Seede AI,一款适合普通人上手的 AI 设计工具,国内


Rokid AI眼镜:连接现实与数字的桥梁,探索下一代智能应用开发
倔强的石头_2025/11/28

@[toc] 前言:当AI遇上AR,未来触手可及 增强现实(AR)技术长久以来都被视为下一代计算平台,它承诺将数字信息无缝叠加到物理世界之上,从而彻底改变我们与信息交互的方式。然而,要将这一愿景变为现实,离不开一个强大、易用且充满活力的开发生态。Rokid AI眼镜及其配套的SDK,正是这样一个旨在赋能开发者的平台,它为我们打开了通往“空间互联网”时代的大门。 本文将聚焦于AI Glasses实践应用,以一个具体的工业场景——AI工业装配助手为例,深入探讨如何利用Rokid平台提供的能力,从概念

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客