Java Stream API通过distinct()或Collectors.toMap()/toSet()实现集合去重:distinct()依赖equals/hashCode且保持顺序;按字段去重需toMap配合合并策略;应避免多次流操作,优先单次链式处理并根据需求选择List或Set。

Java Stream API 提供了简洁、函数式的方式对集合进行去重,核心在于利用 distinct() 方法或结合 Collectors.toMap() / Collectors.toSet() 等收集器实现不同场景下的去重逻辑。
使用 distinct() 实现基础去重
适用于元素类型已正确重写 equals() 和 hashCode() 的情况(如 String、Integer 或自定义类)。该方法基于元素的自然相等性判断,内部使用 LinkedHashSet 保证顺序和唯一性。
- 对 List
去重: List unique = list.stream().distinct().collect(Collectors.toList()); - 注意:若对象未重写 equals/hashCode,distinct() 仅按引用比较,无法按业务字段去重。
按指定字段去重(如 id 或 name)
当需要根据对象某个属性去重(例如保留第一个出现的 User,按 userId 去重),不能直接用 distinct(),需借助 Collectors.toMap() 或辅助 Set 记录已见键值。
- 推荐方式(保持插入顺序,保留首个):
List
unique = list.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(User::getId, u -> u, (u1, u2) -> u1, LinkedHashMap::new),
map -> new ArrayList(map.values())
)); - 更简洁的写法(Java 12+ 可用
Collectors.flatMapping配合 Set,但主流仍用 toMap)。
去重并保留最后出现的元素
默认 toMap 合并函数 (u1, u2) -> u1 保留第一个;改为 (u1, u2) -> u2 即可保留最后一个。
- 例如按 email 去重,取最后一次出现的用户:
Map
map = list.stream()
.collect(Collectors.toMap(User::getEmail, u -> u, (u1, u2) -> u2)); - 结果转为 List 时顺序不保证,如需原序,仍建议用 LinkedHashMap。
避免重复创建中间集合提升性能
链式调用中,多次 stream() 或反复 collect 会带来额外开销。去重后如需继续处理,尽量在单次流中完成。
- 错误示范:先去重再 filter,两次遍历
list.stream().distinct().collect(...);
list.stream().filter(...).collect(...); - 正确做法:合并操作 list.stream().distinct().filter(x -> x.isValid()).map(...).collect(...);
- 对大数据量,优先考虑是否真需 List —— 若仅需唯一值,用
toSet()更高效且语义清晰。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











