HashSet和HashMap都是采用Hash算法来决定其元素的存储,由于HashMap是以键值对的形式存储在集合当中的,此时的hash算法计算的是键(key)的位置,而HashSet计算的是集合中的某一个元素的在集合当中的位置,这个元素就相当于HashMap中的key。
对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:
1. public class HashSet<E>
2. extends AbstractSet<E>
3. implements Set<E>, Cloneable, java.io.Serializable
4. {
5. // 使用 HashMap 的 key 保存 HashSet 中所有元素
6. private transient HashMap<E,Object> map;
7. // 定义一个虚拟的 Object 对象作为 HashMap 的 value
8. private static final Object PRESENT = new Object();
9. ...
10. // 初始化 HashSet,底层会初始化一个 HashMap
11. public HashSet()
12. {
13. map = new HashMap<E,Object>();
14. }
15. // 以指定的 initialCapacity、loadFactor 创建 HashSet
16. // 其实就是以相应的参数创建 HashMap
17. public HashSet(int initialCapacity, float loadFactor)
18. {
19. map = new HashMap<E,Object>(initialCapacity, loadFactor);
20. }
21. public HashSet(int initialCapacity)
22. {
23. map = new HashMap<E,Object>(initialCapacity);
24. }
25. HashSet(int initialCapacity, float loadFactor, boolean dummy)
26. {
27. map = new LinkedHashMap<E,Object>(initialCapacity
28. , loadFactor);
29. }
30. // 调用 map 的 keySet 来返回所有的 key
31. public Iterator<E> iterator()
32. {
33. return map.keySet().iterator();
34. }
35. // 调用 HashMap 的 size() 方法返回 Entry 的数量,就得到该 Set 里元素的个数
36. public int size()
37. {
38. return map.size();
39. }
40. // 调用 HashMap 的 isEmpty() 判断该 HashSet 是否为空,
41. // 当 HashMap 为空时,对应的 HashSet 也为空
42. public boolean isEmpty()
43. {
44. return map.isEmpty();
45. }
46. // 调用 HashMap 的 containsKey 判断是否包含指定 key
47. //HashSet 的所有元素就是通过 HashMap 的 key 来保存的
48. public boolean contains(Object o)
49. {
50. return map.containsKey(o);
51. }
52. // 将指定元素放入 HashSet 中,也就是将该元素作为 key 放入 HashMap
53. public boolean add(E e)
54. {
55. return map.put(e, PRESENT) == null;
56. }
57. // 调用 HashMap 的 remove 方法删除指定 Entry,也就删除了 HashSet 中对应的元素
58. public boolean remove(Object o)
59. {
60. return map.remove(o)==PRESENT;
61. }
62. // 调用 Map 的 clear 方法清空所有 Entry,也就清空了 HashSet 中所有元素
63. public void clear()
64. {
65. map.clear();
66. }
67. ...
68. }
由上面源程序可以看出,HashSet 的实现其实非常简单,它只是封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。
HashSet的绝大部分方法都是通过调用HashMap 的方法来实现的,因此HashSet 和HashMap 两个集合在实现本质上是相同的。