HashMap
和 HashSet
都是Java
中常用的数据结构,它们主要用于存储和快速检索数据,但它们的用途和工作原理有所不同。
HashMap:
-
键值对存储:
HashMap
用于存储“键-值对”
,这意味着每个值(value)都可以通过一个唯一的键(key)访问。比如,你可以把HashMap
想象成一个字典,每个单词(键)都有一个对应的定义(值)。 -
允许null值:
HashMap
允许存储一个null键和多个null值。 -
无序存储:
HashMap
不保证存储顺序,这意味着元素的顺序可能与插入顺序不同。 -
快速访问:由于使用哈希表的结构,
HashMap
能够提供快速的查找、插入和删除操作。
HashMap 示例
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个HashMap实例
HashMap<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("Apple", 3);
map.put("Banana", 2);
map.put("Orange", 5);
// 通过键获取值
System.out.println("Apple: " + map.get("Apple")); // 输出: Apple: 3
// 遍历键值对
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
}
}
HashSet:
-
仅存储唯一元素:
HashSet
仅存储不重复的元素,没有键值对的概念。你可以把它想象成一个存放独特项的集合。 -
基于HashMap:
HashSet
实际上是基于HashMap
实现的,在内部使用一个虚拟的对象作为值来维护元素的唯一性。 -
不允许重复:
HashSet
不允许存储重复的元素。如果尝试添加重复的元素,它将不会覆盖现有的元素。 -
无序存储:
HashSet
同样不保证元素的存储顺序。
HashSet 示例
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
// 创建一个HashSet实例
HashSet<String> set = new HashSet<>();
// 添加元素
set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Apple"); // 尝试添加重复元素
// 显示HashSet中的元素
for (String item : set) {
System.out.println(item);
}
// 输出可能是: Apple, Banana, Orange
// 注意:输出的顺序不一定是插入顺序,因为HashSet不保证顺序
}
}
关键点
- HashMap 展示了如何创建一个键值对映射,并通过键来获取值。
- HashSet 展示了如何仅存储唯一元素,并自动忽略重复项。
讲解 HashMap
和 HashSet
的源码实现可以帮助深入理解它们的区别和用途。以下是对它们的源码实现进行简要的说明和对比。
HashMap 源码解析
-
底层结构:
HashMap
是基于数组和链表(在JDK 8
中,链表在一定条件下会转换为红黑树)实现的。它将键的哈希值用于确定存储位置。 -
节点存储:每个键值对被存储为一个
Node
对象,其中包含了键、值、哈希值和指向下一个节点的指针。 -
哈希函数:
HashMap
使用哈希函数来计算键的哈希值,用于决定元素在数组中的位置。 -
扩容机制:当元素数量超过一个阈值(默认负载因子为
0.75
)时,HashMap
会进行扩容,将容量扩大一倍,同时重新哈希现有元素。
HashSet 源码解析
-
基于HashMap:
HashSet
是通过一个HashMap
实现的。它利用HashMap
的键来存储集合中的元素,所有的值都指向同一个常量对象(通常是一个虚拟的Object
实例)。 -
唯一性:
HashSet
依赖于HashMap
的键的唯一性来保证不存储重复元素。 -
操作简单:
HashSet
的所有基本操作(如添加、删除、查询)都直接委托给内部的HashMap
来完成。
源码对比
- 结构:
HashMap
直接管理键值对,而HashSet
通过HashMap
来管理唯一元素。 - 实现:
HashSet
是对HashMap
的简化使用,主要利用其键的特性。 - 存储内容:
HashMap
存储键值对,HashSet
仅存储唯一的键。
总的来说,HashMap
适用于需要通过键快速访问值的场景,而HashSet
适用于只需要快速访问和管理唯一元素的场景。选择使用哪种数据结构应根据具体需求来决定。