HashSet 本身并没有什么特别的东西,它提供的所有集合核心功能,都是基于 HashMap 来实现的。如果了解 HashMap 源码的实现,HashSet 源码看起来跟玩一样。我的博客中有专门分析 HashMap 源码的文章,不熟悉的请自行翻阅。

    HashSet 的特点如下:

    • 内部使用 HashMap 的 key 存储元素,以此来保证元素不重复
    • HashSet 是无序的,因为 HashMap 的 key 是无序的;
    • HashSet 中允许有一个 null 元素,因为 HashMap 允许 key 为 null;
    • HashSet 是非线程安全的。
    1. public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
    2. static final long serialVersionUID = -5024744406713321676L;
    3. // 基于HashMap实现
    4. private transient HashMap<E,Object> map;
    5. // 只需要用到HashMap中key唯一的特性,所以value全部使用同一个 Object实例填充,节省内存空间
    6. private static final Object PRESENT = new Object();
    7. /**
    8. * 实例化 HashSet 的时候,初始化内部的 HashMap
    9. */
    10. public HashSet() {
    11. map = new HashMap<>();
    12. }
    13. /**
    14. * 根据一个集合实例,实例化 HashSet
    15. */
    16. public HashSet(Collection<? extends E> c) {
    17. map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    18. addAll(c);
    19. }
    20. /**
    21. * 根据初始容量和扩容因子实例化 HashSet,减少rehash频率,提升性能,原理与HashMap相同
    22. */
    23. public HashSet(int initialCapacity, float loadFactor) {
    24. map = new HashMap<>(initialCapacity, loadFactor);
    25. }
    26. /**
    27. * 同上
    28. */
    29. public HashSet(int initialCapacity) {
    30. map = new HashMap<>(initialCapacity);
    31. }
    32. HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    33. map = new LinkedHashMap<>(initialCapacity, loadFactor);
    34. }
    35. /**
    36. * 返回迭代器,用于迭代
    37. * 下面所有的功能都是基于 HashMap 来实现的
    38. */
    39. public Iterator<E> iterator() {
    40. return map.keySet().iterator();
    41. }
    42. /**
    43. * 元素个数
    44. */
    45. public int size() {
    46. return map.size();
    47. }
    48. /**
    49. * 是否为空
    50. */
    51. public boolean isEmpty() {
    52. return map.isEmpty();
    53. }
    54. /**
    55. * 是否包含给定元素
    56. */
    57. public boolean contains(Object o) {
    58. return map.containsKey(o);
    59. }
    60. /**
    61. * 添加元素,如果 Set集合中未包含该元素,返回true
    62. */
    63. public boolean add(E e) {
    64. return map.put(e, PRESENT)==null;
    65. }
    66. /**
    67. * 删除元素,如果Set集合包含该元素,返回true
    68. */
    69. public boolean remove(Object o) {
    70. return map.remove(o)==PRESENT;
    71. }
    72. /**
    73. * 清除元素
    74. */
    75. public void clear() {
    76. map.clear();
    77. }
    78. /**
    79. * 浅克隆
    80. */
    81. @SuppressWarnings("unchecked")
    82. public Object clone() {
    83. try {
    84. HashSet<E> newSet = (HashSet<E>) super.clone();
    85. newSet.map = (HashMap<E, Object>) map.clone();
    86. return newSet;
    87. } catch (CloneNotSupportedException e) {
    88. throw new InternalError(e);
    89. }
    90. }
    91. }