HashSet 和 TreeSet 都是 Java 中 Set 接口的实现类,用于存储不重复的元素,但它们在底层实现、排序、性能、使用场景等方面有明显区别。
| 对比点 | HashSet | TreeSet |
|---|---|---|
| 底层实现 | 哈希表(HashMap) | 红黑树(TreeMap) |
| 是否有序 | ❌ 无序 | ✅ 有序(自然顺序或定制顺序) |
| 是否允许 null | ✅ 允许(最多一个) | ❌ 不允许(会抛 NullPointerException) |
| 元素要求 | 需重写 hashCode() 和 equals() |
需实现 Comparable 或提供 Comparator |
| 时间复杂度 | 增删查:O(1)(平均) | 增删查:O(log n) |
| 性能 | 更快 | 较慢 |
| 线程安全 | ❌ 不安全 | ❌ 不安全 |
HashMap 实现Set<String> set = new HashSet<>();
set.add("banana");
set.add("apple");
set.add("orange");
System.out.println(set);
// 输出顺序不确定
✅ 只需要去重
✅ 不关心顺序
✅ 追求高性能
Set<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(2);
System.out.println(set); // [1, 2, 3]
Set<String> set = new TreeSet<>(Comparator.reverseOrder());
set.add("apple");
set.add("banana");
set.add("orange");
System.out.println(set); // [orange, banana, apple]
✅ 需要元素自动排序
✅ 需要范围查询(如 subSet、headSet、tailSet)
✅ 对顺序有严格要求
class Person {
String name;
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof Person && ((Person) o).name.equals(this.name);
}
}
否则会抛异常:
Set<Person> set = new TreeSet<>(); // Person 未实现 Comparable → ClassCastException
✅ 选 HashSet,如果:
✅ 选 TreeSet,如果:
如果你愿意,我也可以帮你画一张 HashSet vs TreeSet 的底层结构示意图,或者对比 LinkedHashSet。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。