Java Set集合 #
一、Set接口 #
1.1 特点 #
- 不允许重复元素
- 最多包含一个null元素
- 没有索引
1.2 常用方法 #
java
Set<String> set = new HashSet<>();
// 添加
set.add("A");
set.add("B");
// 删除
set.remove("A");
set.clear();
// 判断
set.contains("A");
set.isEmpty();
set.size();
二、HashSet #
2.1 特点 #
- 基于哈希表实现
- 无序
- 查找、添加、删除时间复杂度O(1)
- 允许null元素
2.2 基本使用 #
java
Set<String> set = new HashSet<>();
// 添加
set.add("A");
set.add("B");
set.add("C");
set.add("A"); // 重复元素不会被添加
System.out.println(set); // [A, B, C](顺序不确定)
// 删除
set.remove("B");
// 判断
System.out.println(set.contains("A")); // true
System.out.println(set.contains("B")); // false
// 遍历
for (String s : set) {
System.out.println(s);
}
set.forEach(System.out::println);
2.3 自定义对象 #
java
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
// 使用
Set<Person> set = new HashSet<>();
set.add(new Person("张三", 25));
set.add(new Person("张三", 25)); // 不会重复添加
System.out.println(set.size()); // 1
三、LinkedHashSet #
3.1 特点 #
- 基于哈希表和链表实现
- 保持插入顺序
- 性能略低于HashSet
3.2 基本使用 #
java
Set<String> set = new LinkedHashSet<>();
set.add("C");
set.add("A");
set.add("B");
System.out.println(set); // [C, A, B](保持插入顺序)
3.3 应用场景 #
java
// 去重并保持顺序
List<String> list = Arrays.asList("A", "B", "A", "C", "B");
Set<String> set = new LinkedHashSet<>(list);
System.out.println(set); // [A, B, C]
四、TreeSet #
4.1 特点 #
- 基于红黑树实现
- 元素自然排序
- 不允许null元素
4.2 基本使用 #
java
Set<Integer> set = new TreeSet<>();
set.add(5);
set.add(1);
set.add(3);
set.add(2);
System.out.println(set); // [1, 2, 3, 5](自然排序)
// 字符串排序
Set<String> strings = new TreeSet<>();
strings.add("C");
strings.add("A");
strings.add("B");
System.out.println(strings); // [A, B, C]
4.3 自定义排序 #
java
// 使用Comparator
Set<Integer> set = new TreeSet<>((a, b) -> b - a); // 降序
set.add(5);
set.add(1);
set.add(3);
System.out.println(set); // [5, 3, 1]
// 对象排序
Set<Person> persons = new TreeSet<>(Comparator.comparing(Person::getAge));
persons.add(new Person("张三", 25));
persons.add(new Person("李四", 20));
4.4 NavigableSet方法 #
java
TreeSet<Integer> set = new TreeSet<>(Arrays.asList(1, 3, 5, 7, 9));
// 查找
System.out.println(set.first()); // 1
System.out.println(set.last()); // 9
System.out.println(set.lower(5)); // 3(小于5的最大值)
System.out.println(set.higher(5)); // 7(大于5的最小值)
System.out.println(set.floor(5)); // 5(小于等于5的最大值)
System.out.println(set.ceiling(5)); // 5(大于等于5的最小值)
// 子集
System.out.println(set.headSet(5)); // [1, 3](小于5)
System.out.println(set.tailSet(5)); // [5, 7, 9](大于等于5)
System.out.println(set.subSet(3, 7)); // [3, 5]([3, 7))
五、Set实现类对比 #
| 实现 | 底层 | 排序 | 性能 | null |
|---|---|---|---|---|
| HashSet | 哈希表 | 无序 | 最高 | 允许 |
| LinkedHashSet | 哈希表+链表 | 插入顺序 | 较高 | 允许 |
| TreeSet | 红黑树 | 自然排序 | 较低 | 不允许 |
六、常用操作 #
6.1 去重 #
java
// List去重
List<Integer> list = Arrays.asList(1, 2, 2, 3, 3, 3);
Set<Integer> set = new HashSet<>(list);
System.out.println(set); // [1, 2, 3]
// 保持顺序去重
Set<Integer> linkedSet = new LinkedHashSet<>(list);
System.out.println(linkedSet); // [1, 2, 3]
6.2 集合运算 #
java
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(2, 3, 4));
// 并集
Set<Integer> union = new HashSet<>(set1);
union.addAll(set2);
System.out.println(union); // [1, 2, 3, 4]
// 交集
Set<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
System.out.println(intersection); // [2, 3]
// 差集
Set<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2);
System.out.println(difference); // [1]
6.3 判断子集 #
java
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(1, 2));
System.out.println(set1.containsAll(set2)); // true(set2是set1的子集)
七、总结 #
| 实现 | 使用场景 |
|---|---|
| HashSet | 快速查找,不关心顺序 |
| LinkedHashSet | 需要保持插入顺序 |
| TreeSet | 需要排序 |
Set要点:
- HashSet最快但无序
- LinkedHashSet保持插入顺序
- TreeSet自动排序
- 自定义对象需要重写equals和hashCode
最后更新:2026-03-26