当前位置: 首页 > news >正文

10. Java 中的 HashSet 和 HashMap 有什么区别?

HashSetHashMap 是 Java 集合框架中的两个重要类,它们都基于哈希表(Hash Table)实现,并且在许多方面共享类似的特性。然而,它们的用途和实现上有一些重要的区别。

1. 功能和用途

  • HashSet:

    • HashSet 是一个实现了 Set 接口的集合类,用于存储唯一的元素。集合中的元素不能重复。

    • 它不保证集合的顺序(插入顺序也不保证),并且不允许存储 null 元素(在某些实现中允许一个 null 元素,但如果多次插入 null,也只会保留一个 null)。

    • 主要用于需要确保元素唯一性的场景。

  • HashMap:

    • HashMap 是一个实现了 Map 接口的集合类,用于存储键值对(key-value pair)。每个键是唯一的,但多个键可以映射到相同的值。

    • HashMap 不保证键值对的顺序,也允许一个 null 键和多个 null 值。

    • 主要用于需要通过键快速查找值的场景。

2. 内部实现

  • HashSet 的实现:

    • HashSet 实际上是基于 HashMap 实现的。每当一个元素被添加到 HashSet 中时,HashSet 将这个元素作为 HashMap 的键存储,而 HashMap 的值是一个常量 PRESENT(通常是一个静态的 Object)。

    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;
    ​
    public boolean add(E e) {return map.put(e, PRESENT) == null;
    }
  • HashMap 的实现:

    • HashMap 使用哈希表来存储键值对。键通过 hashCode() 方法计算哈希值,并且哈希冲突通过链表或红黑树处理(在 Java 8 及之后的版本中,链表长度超过一定阈值后会转换为红黑树)。

3. 主要方法

  • HashSet:

    • add(E e): 添加元素到集合中,如果元素已经存在,则不改变集合,返回 false

    • remove(Object o): 从集合中删除指定元素,返回是否成功删除。

    • contains(Object o): 检查集合中是否包含指定元素,返回 truefalse

    • size(): 返回集合中元素的数量。

  • HashMap:

    • put(K key, V value): 将键值对存储到 HashMap 中,如果键已经存在,则更新其对应的值,返回旧值。

    • get(Object key): 根据键查找并返回对应的值,如果键不存在则返回 null

    • remove(Object key): 删除指定键及其对应的值,返回被删除的值。

    • containsKey(Object key): 检查是否存在指定的键,返回 truefalse

    • containsValue(Object value): 检查是否存在指定的值,返回 truefalse

    • size(): 返回 HashMap 中键值对的数量。

4. 使用场景

  • HashSet 的典型使用场景:

    • 当需要存储一组唯一的元素时,如:去除列表中的重复值、检查某个元素是否存在于集合中等。

    HashSet<String> set = new HashSet<>();
    set.add("Apple");
    set.add("Banana");
    set.add("Apple"); // 该操作不会重复添加 "Apple"
  • HashMap 的典型使用场景:

    • 当需要通过键快速查找值时,如:实现字典、缓存等功能。

    HashMap<String, Integer> map = new HashMap<>();
    map.put("Apple", 1);
    map.put("Banana", 2);
    int count = map.get("Apple"); // 返回 1

5. 性能

  • 时间复杂度:

    • HashSetHashMap 的常见操作(如 addremovecontains)的平均时间复杂度都是 O(1),但在最坏情况下(哈希冲突严重)可能退化为 O(n)。

    • HashMap 的查找和插入操作由于涉及键值对,性能可能稍微复杂一些,但总体而言与 HashSet 类似。

  • 空间复杂度:

    • HashMap 由于存储了键值对,因此比 HashSet 占用更多的内存空间。

总结

  • HashSet 用于存储唯一的元素,内部使用 HashMap 实现,其主要关注的是元素的唯一性和快速查找。

  • HashMap 用于存储键值对,支持通过键快速访问值,并允许一个键对应一个值。

  • 选择 HashSet 还是 HashMap 主要取决于你的需求:如果只需要唯一的元素集合,选择 HashSet;如果需要通过键来映射和查找值,选择 HashMap

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 第四章 Java核心类库 第一节 字符串处理
  • 如何用Java SpringBoot+Vue打造高效产品订单管理系统?
  • PHP房屋出售出租多端多平台预约系统小程序源码
  • 微信小程序vue3父组件调用vue2子组件传多个参数方法
  • SQL数据完整性的守护者:主键与唯一键的精妙应用
  • springboot调用sap接口传输数据,RFC协议接口调用,包含linux,windows部署
  • 多线程资源占用问题
  • 【对商城小程序命名的一些建议】
  • SpringBoot3
  • 算法刷题笔记 筛质数(详细注释的C++实现,同时包含朴素筛法、埃氏筛法和线性筛法详细介绍)
  • 2024最新 Jenkins + Docker实战教程(九)- Jenkins实现嵌入式系统的自动化流程
  • Java框架Spring(一)
  • QT+OSG显示一个三维模型
  • 又一个强大的开源编辑器Vditor
  • safari扩展程序开发
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 2017-09-12 前端日报
  • AHK 中 = 和 == 等比较运算符的用法
  • java2019面试题北京
  • JavaScript-Array类型
  • Linux gpio口使用方法
  • maven工程打包jar以及java jar命令的classpath使用
  • MQ框架的比较
  • Python学习之路16-使用API
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • spring boot下thymeleaf全局静态变量配置
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • SpriteKit 技巧之添加背景图片
  • 动态规划入门(以爬楼梯为例)
  • 机器学习学习笔记一
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 应用生命周期终极 DevOps 工具包
  • 智能合约Solidity教程-事件和日志(一)
  • - 转 Ext2.0 form使用实例
  • 容器镜像
  • ​Linux·i2c驱动架构​
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • #window11设置系统变量#
  • $.ajax,axios,fetch三种ajax请求的区别
  • (2020)Java后端开发----(面试题和笔试题)
  • (3)STL算法之搜索
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (C语言)共用体union的用法举例
  • (ros//EnvironmentVariables)ros环境变量
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)大型网站架构演变和知识体系
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET Core Web APi类库如何内嵌运行?
  • .Net程序帮助文档制作