一 、HashSet 的简介
HashSet 继承AbstractSet,实现了Set,Cloneable,Serializable接口。它是用来存储不重复的元素,其内部使用HashMap来存储元素。
二 、HashSet 源码
HashSet 的实现比较简单,源码就300多行, 它的大部分方法都是调用了HashMap中的方法。
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID = -5024744406713321676L; // 使用HashMap来存储元素 private transient HashMap<E,Object> map; // 用来存放在HashMap中的Value private static final Object PRESENT = new Object(); // 空参数构造函数 public HashSet() { // 对应创建空参数的HashMap map = new HashMap<>(); } // 将另外一个Collection中的元素添加到该实例中 public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); // 调用addAll添加Cllection中的元素到该实例中 addAll(c); } // 带初始化容量和加载因子参数 public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } // 带加载因子 public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } // 创建一个LinkedHashMap,在LinkedHashSet就有调用该构造函数创建有插入顺序的HashSet HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } // 调用map的keySet方法创建迭代器 public Iterator<E> iterator() { return map.keySet().iterator(); } // 调用map的size()方法返回容量 public int size() { return map.size(); } // 判断是否为空 public boolean isEmpty() { return map.isEmpty(); } // 判断是否包含了某个对象 // 注意:在HashMap中判断是否存在某个对象有两个判断条件: // 1,判断该对象的判断该对象的hashCode生成的hash值是否相等 // 2,调用equals方法判断 // 只有两个都符合的情况才判断是相等,所以存在HashSet中的对象最好 // 是重写hashCode方法和equals方法 public boolean contains(Object o) { return map.containsKey(o); } // 添加,调用HashMap的put方法 public boolean add(E e) { return map.put(e, PRESENT)==null; } // 移除某个存在的对象,这个方法跟contains方法一样,需要重写hashCode和equals方法才行 public boolean remove(Object o) { return map.remove(o)==PRESENT; } // 清除, 将map中的元素清除也就是清空了HashSet public void clear() { map.clear(); } .... }