stream().distinct()基于equals()和hashcode()去重,保留首次出现元素;自定义对象需重写这两方法,或用collectors.tomap按指定字段去重。

stream().distinct() 是 Java Stream API 提供的去重方法,它基于元素的 equals() 和 hashCode() 判断是否重复,只保留第一次出现的元素。
基本用法:对简单类型去重
对于 String、Integer 等已重写 equals() 和 hashCode() 的类,直接调用 distinct() 即可:
List<string> list = Arrays.asList("a", "b", "a", "c", "b");
List<string> unique = list.stream()
.distinct()
.collect(Collectors.toList());
// 结果:["a", "b", "c"]
</string></string>
对自定义对象去重:必须重写 equals() 和 hashCode()
如果对象没重写这两个方法,默认按引用比较,所有对象都“不相等”,distinct() 就不会去重。
例如有 User 类,想按 id 去重:
public class User {
private Long id;
private String name;
// 构造、getter 省略
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
之后就能正常使用:
List<user> users = Arrays.asList(
new User(1L, "Alice"),
new User(2L, "Bob"),
new User(1L, "Alice2") // id 相同,会被去重
);
List<user> uniqueUsers = users.stream()
.distinct()
.collect(Collectors.toList()); // 只保留第一个 id=1 的对象
</user></user>
按某个字段去重(不改 equals):用 Collectors.toMap
如果不想修改对象的 equals() 逻辑(比如只在某次操作中按 name 去重),可用 Collectors.toMap 替代:
- 以目标字段为 key,整个对象为 value
- 遇到重复 key 时保留第一个(或按需指定合并策略)
- 最后取 map 的 values 集合
List<user> uniqueByName = users.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
User::getName, // key:去重依据
user -> user, // value:对象本身
(u1, u2) -> u1 // 冲突时保留第一个
),
map -> new ArrayList(map.values())
));
</user>
注意事项
-
distinct()是中间操作,需配合终端操作(如collect、forEach)才会执行 - 底层使用
LinkedHashSet维护顺序和去重,所以能保持原始顺序 - 对 null 元素也支持(null 被视为相同值,只保留一个)
- 性能上,时间复杂度约为 O(n),空间复杂度 O(n)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











