Java集合之HashSet源码解析

94 阅读2分钟

构造方法

/**
 * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
 * default initial capacity (16) and load factor (0.75).
 */
public HashSet() {
    map = new HashMap<>();
}

/**
 * Constructs a new set containing the elements in the specified
 * collection.  The <tt>HashMap</tt> is created with default load factor
 * (0.75) and an initial capacity sufficient to contain the elements in
 * the specified collection.
 *
 * @param c the collection whose elements are to be placed into this set
 * @throws NullPointerException if the specified collection is null
 */
public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

/**
 * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
 * the specified initial capacity and the specified load factor.
 *
 * @param      initialCapacity   the initial capacity of the hash map
 * @param      loadFactor        the load factor of the hash map
 * @throws     IllegalArgumentException if the initial capacity is less
 *             than zero, or if the load factor is nonpositive
 */
public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
}

/**
 * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
 * the specified initial capacity and default load factor (0.75).
 *
 * @param      initialCapacity   the initial capacity of the hash table
 * @throws     IllegalArgumentException if the initial capacity is less
 *             than zero
 */
public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}

成员变量

private transient HashMap<E,Object> map;

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

成员方法

add

    /**
     * 将元素放到map中,key是要添加的元素e,value是final修饰的object对象。
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

remove

    /**
     * 从HashMap中移除元素o,如果元素存在返回true,否则返回false
     */
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

size

    /**
     * 返回HashMap中元素的个数
     *
     * @return the number of elements in this set (its cardinality)
     */
    public int size() {
        return map.size();
    }

contains

    /**
     * 判断HashMap中是否包含某个元素
     *
     * @param o element whose presence in this set is to be tested
     * @return <tt>true</tt> if this set contains the specified element
     */
    public boolean contains(Object o) {
        return map.containsKey(o);
    }

isEmpty

    /**
     * 判断HashSet是否是空的
     *
     * @return <tt>true</tt> if this set contains no elements
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

总结

1.HashSet的底层其实是一个HashMap,key是我们存放的元素,其value是一个final修饰的object对象

2.HashSet是无序的,和HashMap一样

3.HashSet也是线程不安全的,我们可以使用Set s = Collections.synchronizedSet(new HashSet(...))包装一个线程安全的Set

4.HashSet中的元素不可重复,因为HashMap中的key不可重复,重复的key会覆盖其value