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

`HashMap`、`Hashtable` 和 `HashSet`的区别

HashMapHashtableHashSet 都是 Java 中常用的集合类,它们的功能和实现有所不同,尽管它们都使用哈希表(hash table)作为底层数据结构。以下是它们之间的主要区别:

1. HashMap 和 Hashtable 的区别

特性HashMapHashtable
线程安全性不支持线程安全(非同步)线程安全,所有方法都加了 synchronized
性能因为没有同步,性能较高(适用于单线程或同步控制由外部管理的场景)由于同步机制,性能相对较差
null 键和值允许一个 null 键和多个 null不允许 null 键和 null
迭代器Iterator(快速失败)Enumerator(过时,不推荐使用)
引入时间从 JDK 1.2 引入从 JDK 1.0 引入
扩容机制默认初始容量是 16,负载因子为 0.75,扩容时容量变为原来的 2 倍同样的扩容机制,但在高并发情况下性能较差

总结:

  • HashMapHashtable 的改进版,不支持线程同步,因此在单线程环境中或者需要外部同步的环境中性能更高。
  • Hashtable 是线程安全的,但性能较差,且其 API 中的 Enumerator 被淘汰,现在通常推荐使用 HashMap 或者更现代的并发集合类。

2. HashMap 和 HashSet 的区别

特性HashMapHashSet
底层数据结构基于哈希表(HashMap 是由 HashMap 实现的,键值对结构)基于哈希表(其实是 HashMap 的包装,元素是集合的键)
元素类型存储键值对(Key-Value),每个键映射到一个值存储单一元素,不存储值,只关心键
键值对每个元素是一个 key-value 对(即包含键和值)每个元素只有一个 key(没有值)
实现接口实现了 Map 接口实现了 Set 接口
重复元素允许重复值,但键不可重复不允许重复元素(没有值的概念)
添加元素的方式使用 put(key, value) 添加元素使用 add(element) 添加元素
用途适用于需要存储键值对的场景适用于存储唯一元素的场景(去重)

总结:

  • HashMap 存储的是键值对(key-value),是一个 Map 类型的集合。
  • HashSet 存储的是唯一的元素,它的底层是基于 HashMap 实现的,实际上,它将每个元素作为 HashMap 的键,并将值设置为一个常量对象。

3. Hashtable 和 HashSet 的区别

特性HashtableHashSet
底层数据结构基于哈希表(Hashtable 是一个 Map 接口的实现类)基于哈希表(实际上是通过 HashMap 实现的,存储唯一元素)
线程安全性线程安全(方法加锁)不支持线程安全(非同步)
元素类型存储键值对(key-value存储单一元素,去重集合
重复元素键不可重复,值可以重复不允许重复元素(没有值的概念)
性能由于方法都加锁,性能较差无锁设计,性能较高
用途适用于存储键值对的线程安全集合适用于存储不重复元素的集合(去重)

总结:

  • Hashtable 是线程安全的 Map 类型,存储的是键值对。
  • HashSet 是非线程安全的集合类,存储唯一的元素(值没有意义,只有键),底层通过 HashMap 实现。

小结

  • HashMap:实现了 Map 接口,存储键值对,线程不安全,允许 null 键和 null 值。
  • Hashtable:线程安全,存储键值对,早期版本的 Map,不允许 null 键和值,性能较低。
  • HashSet:实现了 Set 接口,存储唯一元素,底层实现使用 HashMap,线程不安全。

如果不需要线程安全,建议使用 HashMapHashSet。如果需要线程安全,可以考虑使用 ConcurrentHashMap 或者使用 Collections.synchronizedMap()Collections.synchronizedSet() 来包装非线程安全的集合。

http://www.lryc.cn/news/507598.html

相关文章:

  • Arduino中解析JSON数据
  • linux----文件访问(c语言)
  • 源码分析之Openlayers中MousePosition鼠标位置控件
  • 以ATTCK为例构建网络安全知识图
  • myexcel的使用
  • Unity 上好用的插件
  • Vivado - 远程调试 + 远程综合实现 + vmWare网络配置 + NFS 文件共享 + 使用 VIO 核
  • 双臂机器人
  • 【Lua热更新】上篇
  • Ubuntu批量修改文件名
  • 食家巷大烤馍:岁月沉淀下的麦香传奇
  • harmony UI组件学习(1)
  • BTP Integration Suite CPI Apache Camel
  • vitepress-打包SyntaxError: Element is missing end tag.
  • 【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类
  • Java进程占用的内存有哪些部分?
  • 【华为OD机试真题】【2024年E卷】数值同化-队列BFS(C++/Java/Python)
  • “魔法糖果盒的秘密:用朴素贝叶斯算法猜糖果颜色”
  • linux中docker命令大全
  • Python `str.strip()` 的高级用法详解
  • [蓝桥杯 2019 国 B] 排列数
  • [bug] StarRocks borker load意向之外的bug
  • 2025年前端面试热门题目——HTML|CSS|Javascript|TS知识
  • Linux中部署项目
  • 在 CentOS 上安装 MySQL 8
  • gradle项目下载依赖报错
  • solon 集成 activemq-client (sdk)
  • LRU 缓存
  • 使用ZLMediaKit 开源项目搭建RTSP 服务器
  • 数组晨考2day08