面试官: 请问 HashSet 有哪些特点?
应聘者: HashSet 实现自 set 接口, set 集合中元素无序且不能重复;
面试官: 那么 HashSet 如何保证元素不重复?
应聘者: 因为 HashSet 底层是基于 HashMap 实现的, 当你 new 一个 HashSet 时候, 实际上是 new 了一个 map, 执行 add 方法时, 实际上调用 map 的 put 方法, value 始终是 PRESENT, 所以根据 HashMap 的一个特性: 将一个 key-value 对放入 HashMap 中时, 首先根据 key 的 hashCode() 返回值决定该 Entry 的存储位置, 如果两个 key 的 hash 值相同, 那么它们的存储位置相同. 如果这个两个 key 的 equalus 比较返回 true. 那么新添加的 Entry 的 value 会覆盖原来的 Entry 的 value,key 不会覆盖. 因此, 如果向 HashSet 中添加一个已经存在的元素, 新添加的集合元素不会覆盖原来已有的集合元素;
源码分析
先来看一下无参的构造函数:
- public HashSet() {
- map = new HashMap<>();
- }
很显然, 当你 new 一个 HashSet 的时候, 实际上是 new 了一个 HashMap
再来看一下 add 方法:
- private static final Object PRESENT = new Object();
- public boolean add(E e) {
- return map.put(e, PRESENT)==null;
- }
定义一个虚拟的 Object PRESENT 是向 map 中插入 key-value 对应的 value, 因为 HashSet 中只需要用到 key, 而 HashMap 是 key-value 键值对; 所以, 向 map 中添加键值对时, 键值对的值固定是 PRESENT.
源码中 HashSet 的绝大部分方法都是通过调用 HashMap 的方法来实现的, 其他的方法, 就请大家自己查阅一下源码吧.
来源: https://www.cnblogs.com/marsitman/p/11215892.html