Java Set集合:你的数据去重神器

Java Set集合:你的数据去重神器

各位道友们好,我是会编程的吕洞宾!今天咱们来聊聊Java中的Set集合------这玩意儿就像是数据界的"照妖镜",专门识别和去除重复元素,让你的数据保持独一无二!

什么是Set?

想象一下天庭的仙人名录:每个神仙都是独一无二的,不能有重复。Set就是这样一种不允许重复元素的集合,它就像个严格的守门员,确保每个元素都是"独一份"的。

三大去重高手

1. HashSet - 闪电侠

HashSet就像是个拥有超快查找能力的闪电侠:

java

csharp 复制代码
Set<String> 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

csharp 复制代码
Set<String> 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

csharp 复制代码
Set<String> orderedImmortals = new LinkedHashSet<>();
orderedImmortals.add("吕洞宾");
orderedImmortals.add("何仙姑");
orderedImmortals.add("铁拐李");

// 保持插入顺序!
for (String immortal : orderedImmortals) {
    System.out.println(immortal); // 输出顺序和插入顺序一致
}

特点

  • 保持插入顺序
  • 去重能力与HashSet相同
  • 查找速度接近HashSet

Set的仙法秘籍

基本操作演示

java

csharp 复制代码
Set<String> eightImmortals = new HashSet<>();

// 添加元素
eightImmortals.add("吕洞宾");
eightImmortals.add("钟离权");
eightImmortals.add("蓝采和");

// 检查存在性
System.out.println("有吕洞宾吗?" + eightImmortals.contains("吕洞宾"));

// 删除元素
eightImmortals.remove("蓝采和");

// 获取大小
System.out.println("当前仙人数量:" + eightImmortals.size());

// 清空集合
eightImmortals.clear();

集合运算(数学课时间)

java

ini 复制代码
Set<String> group1 = new HashSet<>(Arrays.asList("吕洞宾", "何仙姑", "铁拐李"));
Set<String> group2 = new HashSet<>(Arrays.asList("钟离权", "蓝采和", "吕洞宾"));

// 并集(所有不重复的元素)
Set<String> union = new HashSet<>(group1);
union.addAll(group2);
System.out.println("所有仙人:" + union);

// 交集(共同拥有的元素)
Set<String> intersection = new HashSet<>(group1);
intersection.retainAll(group2);
System.out.println("共同仙人:" + intersection);

// 差集(A有B没有的元素)
Set<String> difference = new HashSet<>(group1);
difference.removeAll(group2);
System.out.println("group1独有的仙人:" + difference);

遍历的三种仙术

方法一:增强for循环(推荐)

java

erlang 复制代码
for (String immortal : eightImmortals) {
    System.out.println("仙人:" + immortal);
}

方法二:迭代器

java

vbnet 复制代码
Iterator<String> iterator = eightImmortals.iterator();
while (iterator.hasNext()) {
    System.out.println("仙人:" + iterator.next());
}

方法三:Java 8+ Stream API

java

less 复制代码
eightImmortals.stream()
    .filter(immortal -> immortal.startsWith("吕"))
    .forEach(System.out::println);

实战应用场景

场景1:用户去重

java

typescript 复制代码
// 用户注册时检查用户名是否重复
Set<String> registeredUsers = new HashSet<>();

public boolean registerUser(String username) {
    return registeredUsers.add(username); // 如果已存在返回false
}

场景2:标签管理

java

csharp 复制代码
// 文章标签自动去重
Set<String> articleTags = new TreeSet<>(); // 自动排序的标签
articleTags.add("Java");
articleTags.add("编程");
articleTags.add("Java"); // 这个不会重复添加

场景3:权限验证

java

javascript 复制代码
// 检查用户是否有权限
Set<String> userPermissions = new HashSet<>(Arrays.asList("read", "write"));
if (userPermissions.contains("admin")) {
    System.out.println("有管理员权限");
}

性能对比表

操作 HashSet TreeSet LinkedHashSet
添加元素 ⚡️ 超快 🐢 较慢(要排序) ⚡️ 快
查找元素 ⚡️ 超快 🐢 较快 ⚡️ 超快
删除元素 ⚡️ 超快 🐢 较慢 ⚡️ 快
保持顺序 ❌ 不保证 ✅ 自动排序 ✅ 插入顺序

避坑指南

自定义对象的去重

如果Set中存放自定义对象,需要重写equals()和hashCode()方法:

java

typescript 复制代码
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大法!

相关推荐
神奇的程序员18 小时前
从已损坏的备份中拯救数据
运维·后端·前端工程化
Goldn.19 小时前
Java核心技术栈全景解析:从Web开发到AI融合
java· spring boot· 微服务· ai· jvm· maven· hibernate
oden19 小时前
AI服务商切换太麻烦?一个AI Gateway搞定监控、缓存和故障转移(成本降40%)
后端·openai·api
李慕婉学姐20 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_7400437320 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
编织幻境的妖20 小时前
SQL查询连续登录用户方法详解
java·数据库·sql
未若君雅裁20 小时前
JVM面试篇总结
java·jvm·面试
kk哥889921 小时前
C++ 对象 核心介绍
java·jvm·c++
招风的黑耳21 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
xunyan623421 小时前
面向对象(下)-接口的理解
java·开发语言