常用集合之HashSet原始碼淺析
阿新 • • 發佈:2019-02-20
類圖
原始碼
構造方法
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
//儲存資料的物件,由此就可以看書HashSet是HashMap來實現的
private transient HashMap<E,Object> map;
//是所有寫入 map 的 value 值。
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
//PRESENT是所有寫入 map 的 value 值。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
//...
}
偷偷告訴你,HashSet
中沒有 get
方法。
比較關鍵的就是這個add()
方法。 可以看出它是將存放的物件當做了 HashMap
的健,value
都是相同的 PRESENT
。由於 HashMap
的 key
是不能重複的,所以每當有重複的值寫入到HashSet
時,value
會被覆蓋,但 key
不會受到影響,這樣就保證了HashSet
中只能存放不重複的元素。
這裡又要多問一句了,為什麼HashMap
的鍵值是不重複的呢?因為在HashMap
的原始碼中,是使用key
的hashCode
和key
值去 取值的,hashCode總不能重複吧。這就有源有頭了!
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
ps: 文末推薦其他幾篇有關集合的文章: