HashSet和HashMap有啥区别?一文搞懂Java集合的核心用法

刚学Java的小伙伴经常会困惑:HashSetHashMap名字里都有"Hash",到底有啥不一样?什么时候该用哪个?今天就用最通俗的例子,带你搞懂这两个常用集合类的核心区别,看完再也不会用错啦!

一、先打个比方:它们像生活中的什么?

  • HashSet:像一个“去重的盒子”,只能装单个元素,而且自动帮你去掉重复的。
    比如:往盒子里放“苹果”“香蕉”“苹果”,最后盒子里只剩“苹果”和“香蕉”。

  • HashMap:像一本“字典”,每个元素都是“单词+解释”的组合(键+值),通过“单词”能快速查到“解释”。
    比如:存“apple=苹果”“banana=香蕉”,通过“apple”就能立刻找到“苹果”。

二、核心区别1:存的数据类型不一样

1. HashSet:存“单个元素”,不允许重复

  • 存储形式:只存一个值(比如StringInteger或自定义对象),每个元素唯一(重复元素会被自动忽略)。
  • 代码示例
    HashSet<String> set = new HashSet<>();
    set.add("张三");
    set.add("李四");
    set.add("张三"); // 重复,不会被存入
    System.out.println(set.size()); // 输出2(只有两个不同元素)
    

2. HashMap:存“键值对”,键不能重复,值可以重复

  • 存储形式:每个元素是key-value对,通过keyvalue,类似“索引+数据”的关系。
  • 代码示例
    HashMap<String, Integer> map = new HashMap<>();
    map.put("张三", 18); // 键是“张三”,值是18
    map.put("李四", 20);
    map.put("张三", 22); // 键重复,会覆盖之前的值(18→22)
    System.out.println(map.get("张三")); // 输出22(最新值)
    

三、核心区别2:底层其实是“一家人”!

你可能想不到:HashSet的底层其实就是HashMap

  • HashSet的每个元素,其实是作为HashMap的“键”存在的,而值统一用一个默认的对象(private static final Object PRESENT = new Object();)。
  • 所以:
    • HashSet的去重逻辑,其实就是HashMap“键不能重复”的特性;
    • HashSet的其他操作(添加、删除、查询),本质上都是调用HashMap的对应方法。

四、其他关键区别:一张表对比清楚

特性HashSetHashMap
存储结构单个元素(值)键值对(key-value)
是否允许重复元素不可重复(自动去重)键不可重复,值可重复
是否允许null允许1个null元素允许1个null键,多个null值
常用方法add()contains()size()put()get()entrySet()
本质底层是HashMap(只用键,值固定)独立的键值对存储结构
典型场景去重、判断元素是否存在(如黑名单)快速通过“键”查“值”(如用户ID查信息)

五、什么时候该选谁?举几个例子

1. 选HashSet的场景:

  • 去重需求:比如统计用户输入过哪些不重复的关键词。
    HashSet<String> keywords = new HashSet<>();
    keywords.add("Java");
    keywords.add("Java"); // 无效,自动去重
    
  • 判断元素是否存在:比如检查一个用户名是否已注册(比List快100倍!)。
    if (users.contains("admin")) {
        System.out.println("用户名已存在");
    }
    

2. 选HashMap的场景:

  • 键值对映射:比如存储学生学号和成绩,通过学号快速查成绩。
    HashMap<String, Integer> scores = new HashMap<>();
    scores.put("S001", 90);
    System.out.println("S001的成绩是:" + scores.get("S001"));
    
  • 分组统计:比如统计每个单词出现的次数。
    String text = "apple banana apple orange";
    String[] words = text.split(" ");
    HashMap<String, Integer> countMap = new HashMap<>();
    for (String word : words) {
        countMap.put(word, countMap.getOrDefault(word, 0) + 1);
    }
    // 结果:apple=2, banana=1, orange=1
    

六、零基础也能懂的底层原理

1. 为什么它们都叫“Hash”?

因为它们都用了“哈希表”(Hash Table)结构:

  • 通过哈希函数把元素“计算”到一个固定位置存储,查询时直接通过哈希值定位,速度极快(平均O(1)时间)。

2. 遇到重复怎么办?

  • HashSet:如果添加重复元素,会发现“键”已经存在,直接忽略;
  • HashMap:如果插入重复的键,会用新的值覆盖旧值(就像字典里同一个单词被重新解释)。

七、总结:一句话分清两者

  • HashSet:“去重的单身集合”,只存单个元素,自动去重,适合判断“有没有”;
  • HashMap:“配对的情侣集合”,存键值对,通过键快速找值,适合“根据XX查XX”。

下次遇到需要“去重”或“键值映射”的场景,再也不用担心选错啦!如果还有疑问,欢迎在评论区留言~ 😊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农技术栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值