在 Java 里,Comparator 本身不能“直接去重”,但可以和 Set / Stream 配合,实现“按某种规则去重”。下面按常见场景给你讲清楚,并附示例代码。
TreeSet(Comparator)Stream.distinct() ❌(不能用 Comparator)Stream.collect(Collectors.toMap / groupingBy) ✅TreeSet + Comparator 去重(最常用)class User {
int id;
String name;
User(int id, String name) {
this.id = id;
this.name = name;
}
}
id 去重List<User> list = List.of(
new User(1, "A"),
new User(1, "B"),
new User(2, "C")
);
Set<User> set = new TreeSet<>(
Comparator.comparingInt(User::getId)
);
set.addAll(list);
System.out.println(set);
✅ 结果:只保留一个 id=1 的元素
⚠️ 注意
TreeSet 认为:compare(a, b) == 0 → a 和 b 相同
Set<User> set = new TreeSet<>(
Comparator.comparing(User::getName)
.thenComparing(User::getId)
);
Collectors.toMapList<User> result = list.stream()
.collect(Collectors.toMap(
User::getId, // 去重 key
u -> u, // 保留 value
(a, b) -> a // 冲突时保留谁
))
.values()
.stream()
.toList();
✅ 可读性好
✅ 不依赖 equals / hashCode
Stream.distinct()(❌ 不能用 Comparator)// ❌ 错误示例
list.stream().distinct(comparator); // 不存在
distinct() 只能依赖:
equals()hashCode()Comparator<User> byId = Comparator.comparingInt(User::getId);
@Override
public boolean equals(Object o) {
return o instanceof User u && u.id == this.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
然后:
Set<User> set = new HashSet<>(list);
⚠️ Comparator 和 equals 不一致时,逻辑会很混乱
| 方式 | 是否用 Comparator | 是否推荐 |
|---|---|---|
| TreeSet + Comparator | ✅ | ✅ |
| Stream + toMap | ❌ | ✅✅ |
| Stream.distinct | ❌ | ❌ |
| HashSet + equals | ❌ | ⚠️ |
去重 ≠ Comparator
Comparator 用来定义“怎么算相同”
TreeSet / Stream 用来真正去重
如果你有具体场景(比如去重 List、Map、JSON、数据库结果),可以直接贴代码,我可以帮你写最优解。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。