1. 程式人生 > >HashSet源碼分析 jdk1.6

HashSet源碼分析 jdk1.6

nsa body contain mod com contains odi retain actor

Set的特點:Set元素無順序,且元素不可以重復。

1、定義

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable

Set接口定義:

public interface Set<E> extends Collection<E> {
    // Query Operations
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator
<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); // Modification Operations boolean add(E e); boolean remove(Object o); // Bulk Operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean retainAll(Collection<?> c);
boolean removeAll(Collection<?> c); void clear(); // Comparison and hashing boolean equals(Object o); int hashCode(); }

2、底層存儲

// 底層使用HashMap來保存HashSet的元素
    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    // 由於Set只使用到了HashMap的key,所以此處定義一個靜態的常量Object類,來充當HashMap的value
//用於避免java.lang.NullPointerException異常
private static final Object PRESENT = new Object();

3、構造方法

/**
     * 使用HashMap的默認容量大小16和默認加載因子0.75初始化map,構造一個HashSet
     */
    public HashSet() {
        map = new HashMap<E,Object>();
    }

    /**
     * 構造一個指定Collection參數的HashSet,這裏不僅僅是Set,只要實現Collection接口的容器都可以
     */
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<E,Object>(Math. max((int) (c.size()/.75f) + 1, 16));
       // 使用Collection實現的Iterator叠代器,將集合c的元素一個個加入HashSet中
       addAll(c);
    }

    /**
     * 使用指定的初始容量大小和加載因子初始化map,構造一個HashSet
     */
    public HashSet( int initialCapacity, float loadFactor) {
        map = new HashMap<E,Object>(initialCapacity, loadFactor);
    }

    /**
     * 使用指定的初始容量大小和默認的加載因子0.75初始化map,構造一個HashSet
     */
    public HashSet( int initialCapacity) {
        map = new HashMap<E,Object>(initialCapacity);
    }

    /**
     * 不對外公開的一個構造方法(默認default修飾),底層構造的是LinkedHashMap,dummy只是一個標示參數,無具體意義
     */
    HashSet( int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}

4、增加和刪除

/**
     * 利用HashMap的put方法實現add方法
     */
    public boolean add(E e) {
        return map .put(e, PRESENT)== null;
    }

    /**
     * 利用HashMap的remove方法實現remove方法
     */
    public boolean remove(Object o) {
        return map .remove(o)==PRESENT;
    }

    /**
     * 添加一個集合到HashSet中,該方法在AbstractCollection中
     */
    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
       // 取得集合c叠代器Iterator
       Iterator<? extends E> e = c.iterator();
       // 遍歷叠代器
        while (e.hasNext()) {
           // 將集合c的每個元素加入到HashSet中
           if (add(e.next()))
              modified = true;
       }
        return modified;
    }
    
    /**
     * 刪除指定集合c中的所有元素,該方法在AbstractSet中
     */
    public boolean removeAll(Collection<?> c) {
        boolean modified = false;

        // 判斷當前HashSet元素個數和指定集合c的元素個數,目的是減少遍歷次數
        if (size() > c.size()) {
            // 如果當前HashSet元素多,則遍歷集合c,將集合c中的元素一個個刪除
            for (Iterator<?> i = c.iterator(); i.hasNext(); )
                modified |= remove(i.next());
        } else {
            // 如果集合c元素多,則遍歷當前HashSet,將集合c中包含的元素一個個刪除
            for (Iterator<?> i = iterator(); i.hasNext(); ) {
                if (c.contains(i.next())) {
                    i.remove();
                    modified = true;
                }
            }
        }
        return modified;
}

Hashset的很多地方就是利用 hashmap的key實現的

HashSet源碼分析 jdk1.6