HashSet源碼分析 jdk1.6
阿新 • • 發佈:2018-03-10
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