JAVA集合框架12---HashSet(JDK1.7)源码解析

上一篇我们分析了HashMap的源码,底层就是一个可变长数组+单向链表实现的,这篇我们接着分析一下HashSet的源码。HashSet是Set接口的一种实现方式,前面我们已经说过了,Set接口继承自Collection接口,但是Set接口并没有扩展任何方法,只是要求实现类保证Set集合内没有重复元素。在上一篇中我们知道HashMap中的key是唯一的,它不是正好满足了Set接口的要求吗。实际上HashSet就是这么实现的,使用HashMap的key来当做Set集合的实现,我们来看源码:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    // 保存着一个HashMap的实例
    private transient HashMap<E,Object> map;
    // map接口是key-value类型的,但是Set接口只需要key就够了,所以HashMap中所有的value都是下面这个默认值了。
    private static final Object PRESENT = new Object();
    // 无参构造方法,初始化map
    public HashSet() {
        map = new HashMap<>();
    }

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);  // addAll() 方法在AbstractCollection中提供了默认实现,这就是继承抽象类的好处
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }
    public boolean isEmpty() {
        return map.isEmpty();
    }
    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继承自AbstractSet类,AbstractSet提供了Set接口的默认实现,和AbstractCollection与Collection,AbstractList与List之间的关系是一样的。AbstractSet继承自AbstractCollection类。

猜你喜欢

转载自blog.csdn.net/qq_22158743/article/details/87933587