HashSet是最常用的Set集合之一,可以保证元素的唯一性。
- 底层原理
底层就是HashMap,存储的元素为HashMap的key,HashMap的value默认存储了一个Object的静态常量PRESENT - 构造方法
public HashSet() { map = new HashMap<>(); } public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
- add/remove/contains等方法
也都调用的HashMap的相应方法public Iterator<E> iterator() { // 迭代,其实为HashMap的key的迭代 return map.keySet().iterator(); } public boolean contains(Object o) { return map.containsKey(o); } public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; } public void clear() { map.clear(); }
- 保证唯一性
HashSet调用HashMap的put方法,而put方法中有一行逻辑,哈希值与key都相同,会直接用新值覆盖旧值。HashSet利用这一特性来保证唯一性。
所以,存放对象时需要重写hashCode与equals方法,否则就会出现,两个对象的key值(各种属性值)相同,但由于哈希值不同,而出现重复存储。
参考:
https://segmentfault.com/a/1190000021434077
Java源码