stream.distinct()基于equals()和hashcode()去重,保留首次出现元素;自定义类需重写这两方法,否则按引用比较;第三方类可用collectors.tomap按字段去重。

Stream.distinct() 是 Java 8 引入的 Stream API 中用于去重的中间操作,它基于元素的 equals() 和 hashCode() 方法判断是否重复,只保留首次出现的元素。
基本用法:对简单类型去重
对于 String、Integer 等已重写 equals 和 hashCode 的类型,直接调用 distinct() 即可:
- 原始数据:
List<string> list = Arrays.asList("a", "b", "a", "c");</string> - 去重操作:
list.stream().distinct().collect(Collectors.toList()); - 结果:
[a, b, c](顺序保持不变)
对自定义对象去重:必须重写 equals 和 hashCode
若要对自定义类(如 User)按某个字段(如 id)去重,必须在该类中正确重写 equals() 和 hashCode(),否则 distinct() 会按引用比较,所有对象都被视为不同。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 错误示例:未重写方法 → 每个 new User() 都是“不同”的
- 正确做法:用 IDE 自动生成(如 IntelliJ 的
Alt+Insert → equals and hashCode),确保关键字段(如id)参与计算 - 示例:若两个
User对象id相同,则distinct()视为重复,仅保留第一个
按特定字段去重(不修改原类):用 Collectors.toMap 替代
当无法修改类(如第三方类)或只想按某字段(如 name)去重时,distinct() 不适用。可用 Collectors.toMap 实现逻辑去重:
- 语法:
stream.collect(Collectors.toMap(User::getName, user -> user, (u1, u2) -> u1)) - 含义:以
name为 key,User 为 value;遇到重复 key 时保留第一个(u1) - 再转回 List:
new ArrayList(map.values()) - 注意:此方式不保证原始顺序(除非用
LinkedHashMap)
性能与注意事项
distinct() 内部使用 HashSet 缓存已见元素,因此要求元素可哈希(即 hashCode() 稳定且与 equals() 一致)。
- 时间复杂度:平均 O(n),最坏 O(n²)(哈希冲突严重时)
- 线程不安全:不要在并行流中对非线程安全对象使用 distinct(除非对象本身线程安全)
- 空值处理:null 元素会被正常去重(多个 null 只保留一个),但若
equals()实现有误,可能出错
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










