java源碼閱讀HashSet

來源:互聯網
上載者:User

標籤:static   檢查   eof   htm   catch   過多   poi   math   ble   

1類簽名與註解

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

此類實現Set介面,由雜湊表(實際為HashMap執行個體)支援。 對集合的迭代次序不作任何保證。特別是,它不能保證順序在一段時間內保持不變(HashMap的擴容重hash)。 這個類允許null元素。

請注意,此實現不同步。 如果多個線程並發訪問雜湊集,並且至少有一個線程修改該集合,那麼它必須在外部進行同步。 這通常通過在自然地封裝集合的一些對象上進行同步來實現。 如果沒有這樣的對象存在,那麼該集合應該使用Collections.synchronizedSet方法“封裝”。 這最好在建立時完成,以防止對該集合的意外不同步訪問:

 Set s = Collections.synchronizedSet(new HashSet(...)); 

該類iterator方法返回的迭代器是故障快速的。此機制在HashMap一節中有詳細講述。

 

2屬性

static final long serialVersionUID = -5024744406713321676L;private transient HashMap<E,Object> map;// Map中的一個虛擬值private static final Object PRESENT = new Object();

HashSet是通過HashMap實現的,所以內部持有map的引用,Set的值對應著Map中的key,但是每次map的插入需要是<key,value>的索引值對,所以就有了虛擬value對象,就是PRESENT。

 

3構造方法

//1預設public HashSet() {        map = new HashMap<>();    }//2通過集合構造public HashSet(Collection<? extends E> c) {        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));        addAll(c);    }//3指定HashMap的初始化容量和負載因子public HashSet(int initialCapacity, float loadFactor) {        map = new HashMap<>(initialCapacity, loadFactor);    }//4指定HashMap的初始化容量public HashSet(int initialCapacity) {        map = new HashMap<>(initialCapacity);    }//5指定初始化容量和負載因子,內部通過LinkedHashMap實現HashSet(int initialCapacity, float loadFactor, boolean dummy) {        map = new LinkedHashMap<>(initialCapacity, loadFactor);    }

注意:構造方法5的dummy參數其實沒有特別的意義,唯一作用是通過多一個參數來區別構造方法3(方法重載)。

 

4常用方法

(1)add

public boolean add(E e) {        return map.put(e, PRESENT)==null;    }

(2)remove

public boolean remove(Object o) {        return map.remove(o)==PRESENT;    }

(3)contains

public boolean contains(Object o) {        return map.containsKey(o);    }

(4)其他常用

public Iterator<E> iterator() {        return map.keySet().iterator();    }public int size() {        return map.size();    }public boolean isEmpty() {        return map.isEmpty();    }

HashSet的常用方法都是通過調用HashMap的方法實現的。

 

5其他

(1)clone

public Object clone() {        try {            HashSet<E> newSet = (HashSet<E>) super.clone();            newSet.map = (HashMap<E, Object>) map.clone();            return newSet;        } catch (CloneNotSupportedException e) {            throw new InternalError(e);        }    }

(2)序列化與還原序列化

//序列化private void writeObject(java.io.ObjectOutputStream s)        throws java.io.IOException {        // Write out any hidden serialization magic        s.defaultWriteObject();        // Write out HashMap capacity and load factor        s.writeInt(map.capacity());        s.writeFloat(map.loadFactor());        // Write out size        s.writeInt(map.size());        // Write out all elements in the proper order.        for (E e : map.keySet())            s.writeObject(e);    }//還原序列化  private void readObject(java.io.ObjectInputStream s)        throws java.io.IOException, ClassNotFoundException {        // Read in any hidden serialization magic        s.defaultReadObject();        // 讀capacity(檢查非負).        int capacity = s.readInt();        if (capacity < 0) {            throw new InvalidObjectException("Illegal capacity: " + capacity);        }        // 讀負載因子(不能為null).        float loadFactor = s.readFloat();        if (loadFactor <= 0 || Float.isNaN(loadFactor)) {            throw new InvalidObjectException("Illegal load factor: " + loadFactor);        }        // Read size and verify non-negative.        int size = s.readInt();        if (size < 0) {            throw new InvalidObjectException("Illegal size: " + size);        }        // 計算需要的capacity        capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),                HashMap.MAXIMUM_CAPACITY);        // Constructing the backing map will lazily create an array when the first element is        // added, so check it before construction. Call HashMap.tableSizeFor to compute the        // actual allocation size. Check Map.Entry[].class since it‘s the nearest public type to        // what is actually created.        SharedSecrets.getJavaOISAccess()                     .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));        // 構造HashMap對象        map = (((HashSet<?>)this) instanceof LinkedHashSet ?               new LinkedHashMap<E,Object>(capacity, loadFactor) :               new HashMap<E,Object>(capacity, loadFactor));        // 往HashMap中添加索引值對        for (int i=0; i<size; i++) {            @SuppressWarnings("unchecked")                E e = (E) s.readObject();            map.put(e, PRESENT);        }    }

(3)equals

HashSet類中沒有實現equls方法,而是從父類AbstractSet中繼承過來的。AbstractSet中equls實現如下:

public boolean equals(Object o) {        if (o == this)            return true;        if (!(o instanceof Set))            return false;        Collection<?> c = (Collection<?>) o;        if (c.size() != size())            return false;        try {            return containsAll(c);        } catch (ClassCastException unused)   {            return false;        } catch (NullPointerException unused) {            return false;        }    }public boolean containsAll(Collection<?> c) {        for (Object e : c)            if (!contains(e))                return false;        return true;    }public boolean contains(Object o) {        Iterator<E> it = iterator();        if (o==null) {            while (it.hasNext())                if (it.next()==null)                    return true;        } else {            while (it.hasNext())                if (o.equals(it.next()))                    return true;        }        return false;    }

equals首先判斷是否引用同1個對象,若是則返回true。

否則,判斷是否都是Set類型的,若不是則返回false。

若是,判斷是否都有相等的size,若不是則返回false。

若是,則調用containsAll是否包含所有元素,若是則返回true,否則返回false。

 

java源碼閱讀HashSet

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.