Java Set集合:你的数据去重神器
各位道友们好,我是会编程的吕洞宾!今天咱们来聊聊Java中的Set集合——这玩意儿就像是数据界的\”照妖镜\”,专门识别和去除重复元素,让你的数据保持独一无二!
什么是Set?
想象一下天庭的仙人名录:每个神仙都是独一无二的,不能有重复。Set就是这样一种不允许重复元素的集合,它就像个严格的守门员,确保每个元素都是\”独一份\”的。
三大去重高手
1. HashSet – 闪电侠
HashSet就像是个拥有超快查找能力的闪电侠:
Set immortalSet = new HashSet();
immortalSet.add(\"吕洞宾\");
immortalSet.add(\"何仙姑\");
immortalSet.add(\"铁拐李\");
immortalSet.add(\"吕洞宾\"); // 这个不会重复添加!
System.out.println(immortalSet.size()); // 输出:3
特点:
- 基于哈希表,查找速度超快(O(1)时间复杂度)
- 不保证元素顺序(就像神仙们随意站队)
- 允许null元素(但只能有一个null)
2. TreeSet – 排序大师
TreeSet就像是个自动整理队伍的纪律委员:
java
Set sortedImmortals = new TreeSet();
sortedImmortals.add(\"钟离权\");
sortedImmortals.add(\"蓝采和\");
sortedImmortals.add(\"吕洞宾\");
// 自动按字典序排序!
for (String immortal : sortedImmortals) {
System.out.println(immortal); // 输出:蓝采和、吕洞宾、钟离权
}
特点:
- 基于红黑树,自动排序
- 查找速度较快(O(log n)时间复杂度)
- 不允许null元素
3. LinkedHashSet – 有序去重专家
LinkedHashSet就像是既保持顺序又去重的完美主义者:
java
Set orderedImmortals = new LinkedHashSet();
orderedImmortals.add(\"吕洞宾\");
orderedImmortals.add(\"何仙姑\");
orderedImmortals.add(\"铁拐李\");
// 保持插入顺序!
for (String immortal : orderedImmortals) {
System.out.println(immortal); // 输出顺序和插入顺序一致
}
特点:
- 保持插入顺序
- 去重能力与HashSet相同
- 查找速度接近HashSet
Set的仙法秘籍
基本操作演示
java
Set eightImmortals = new HashSet();
// 添加元素
eightImmortals.add(\"吕洞宾\");
eightImmortals.add(\"钟离权\");
eightImmortals.add(\"蓝采和\");
// 检查存在性
System.out.println(\"有吕洞宾吗?\" + eightImmortals.contains(\"吕洞宾\"));
// 删除元素
eightImmortals.remove(\"蓝采和\");
// 获取大小
System.out.println(\"当前仙人数量:\" + eightImmortals.size());
// 清空集合
eightImmortals.clear();
集合运算(数学课时间)
java
Set group1 = new HashSet(Arrays.asList(\"吕洞宾\", \"何仙姑\", \"铁拐李\"));
Set group2 = new HashSet(Arrays.asList(\"钟离权\", \"蓝采和\", \"吕洞宾\"));
// 并集(所有不重复的元素)
Set union = new HashSet(group1);
union.addAll(group2);
System.out.println(\"所有仙人:\" + union);
// 交集(共同拥有的元素)
Set intersection = new HashSet(group1);
intersection.retainAll(group2);
System.out.println(\"共同仙人:\" + intersection);
// 差集(A有B没有的元素)
Set difference = new HashSet(group1);
difference.removeAll(group2);
System.out.println(\"group1独有的仙人:\" + difference);
遍历的三种仙术
方法一:增强for循环(推荐)
java
for (String immortal : eightImmortals) {
System.out.println(\"仙人:\" + immortal);
}
方法二:迭代器
java
Iterator<String> iterator = eightImmortals.iterator();
while (iterator.hasNext()) {
System.out.println(\"仙人:\" + iterator.next());
}
方法三:Java 8+ Stream API
java
eightImmortals.stream()
.filter(immortal -> immortal.startsWith(\"吕\"))
.forEach(System.out::println);
实战应用场景
场景1:用户去重
java
// 用户注册时检查用户名是否重复
Set<String> registeredUsers = new HashSet();
public boolean registerUser(String username) {
return registeredUsers.add(username); // 如果已存在返回false
}
场景2:标签管理
java
// 文章标签自动去重
Set articleTags = new TreeSet(); // 自动排序的标签
articleTags.add(\"Java\");
articleTags.add(\"编程\");
articleTags.add(\"Java\"); // 这个不会重复添加
场景3:权限验证
java
// 检查用户是否有权限
Set<String> userPermissions = new HashSet(Arrays.asList(\"read\", \"write\"));
if (userPermissions.contains(\"admin\")) {
System.out.println(\"有管理员权限\");
}
性能对比表
| 操作 | HashSet | TreeSet | LinkedHashSet |
|---|---|---|---|
| 添加元素 | ️ 超快 | 较慢(要排序) | ️ 快 |
| 查找元素 | ️ 超快 | 较快 | ️ 超快 |
| 删除元素 | ️ 超快 | 较慢 | ️ 快 |
| 保持顺序 | 不保证 | 自动排序 | 插入顺序 |
避坑指南
自定义对象的去重
如果Set中存放自定义对象,需要重写equals()和hashCode()方法:
java
class Immortal {
private String name;
private int age;
public Immortal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Immortal immortal = (Immortal) o;
return age == immortal.age && Objects.equals(name, immortal.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
// 现在可以正确去重了
Set<Immortal> immortals = new HashSet();
immortals.add(new Immortal(\"吕洞宾\", 1000));
immortals.add(new Immortal(\"吕洞宾\", 1000)); // 这个不会重复添加
选择口诀
- 要最快查找:用HashSet
- 要自动排序:用TreeSet
- 要保持插入顺序:用LinkedHashSet
- 存放自定义对象:记得重写equals和hashCode!
总结
Set就像是Java世界的\”去重大师\”:
- HashSet:闪电查找,适合大多数场景
- TreeSet:自动排序,需要有序时使用
- LinkedHashSet:保持顺序,需要记录插入顺序时使用
记住:Set的核心使命就是去重!当你需要确保元素唯一性时,请毫不犹豫地请出Set大法!
