HashSet部分源碼分析

  今天來簡單講講HashSet,因爲HashSet實際上是基於HashMap來實現的,底層使用HashMap來保存集合元素,關於HashMap會在接下來的博客中加以介紹,所以這次HashSet就簡單寫一寫了。(以下都是基於jdk1.8)

繼承樹

HashSet的繼承樹如下圖:
在這裏插入圖片描述

類註釋解析

(1)基於HashMap實現,不能保證集合的迭代順序;特別是它不能保證元素的順序不隨時間而改變。且允許null值。

This class implements the <tt>Set</tt> interface, backed by a hash table
  (actually a <tt>HashMap</tt> instance).  It makes no guarantees as to the
  iteration order of the set; in particular, it does not guarantee that the
 order will remain constant over time. This class permits the <tt>null</tt>
 element.

(2)線程不安全。

Note that this implementation is not synchronized.

可通過如下方式使用線程安全的操作:

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

(3)通過集合的iterator方法返回的迭代器實現了快速失敗機制,如果迭代器被創建之後,集合被修改(除了迭代器自己的remove方法修改),迭代器將會拋出ConcurrentModificationException異常。因此,在併發修改的情況下,迭代器會快速失敗,而不會等待。
  需要注意的是,它不能保證在非併發修改的情況下,快速報錯不會被觸發,迭代器只能盡力而爲。因此,不應該編寫一段依賴ConcurrentModificationException異常的程序。迭代器的快速報錯應該只用於檢測Bug.

 * <p>The iterators returned by this class's <tt>iterator</tt> method are
 * <i>fail-fast</i>: if the set is modified at any time after the iterator is
 * created, in any way except through the iterator's own <tt>remove</tt>
 * method, the Iterator throws a {@link ConcurrentModificationException}.
 * Thus, in the face of concurrent modification, the iterator fails quickly
 * and cleanly, rather than risking arbitrary, non-deterministic behavior at
 * an undetermined time in the future.
 *
 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
 * as it is, generally speaking, impossible to make any hard guarantees in the
 * presence of unsynchronized concurrent modification.  Fail-fast iterators
 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
 * Therefore, it would be wrong to write a program that depended on this
 * exception for its correctness: <i>the fail-fast behavior of iterators
 * should be used only to detect bugs.</i>
源碼之旅

(1)使用不需要序列化的HashMap類型的對象來保存集合元素

private transient HashMap<E,Object> map;

(2)默認initial capacity是16,load factor 是0.75

    /**
     * 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<>();
    }

(3)指定初始容量大小和加載因子的構造函數。

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

(4)指定初始容量大小的構造函數。

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

(5)常用方法:

	public Iterator<E> iterator() {
	    return map.keySet().iterator();
	}
	
    public int size() {
        return map.size();
    }
    
    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();
    }

  可以看到這些方法都是用的HashMap的方法,留待後面講HashMap的時候再詳細總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章