Map容器家族(AbstractMap原始碼詳解)
阿新 • • 發佈:2018-12-10
一、在Map集合體系中的位置及概述
AbstractMap抽象類提供Map介面的骨幹實現,以最大限度地減少實現此介面所需的工作量。
二、成員變數
// 儲存key
transient Set<K> keySet;
// 儲存value
transient Collection<V> values;
三、方法詳解
1.新增方法
/** * 功能:向map中新增元素 * 注:這個方法並沒有實現 */ public V put(K key, V value) { throw new UnsupportedOperationException(); }
2.刪除方法
/**
* 功能:刪除所有鍵值對
* 實現:
* 1.呼叫Set集合的clear方法進行刪除
*/
public void clear() {
entrySet().clear();
}
3.修改方法(Modification Operations)
/** * 功能:根據鍵移除該鍵值對 * 實現: * 1.獲取儲存Entry的Set迭代器,並建立臨時儲存要刪除的Entry的變數correctEntry * 2.如果待刪除的key為null: * 2.1 如果correctEntry中沒有元素並且有下一個元素進行迭代,比較key值是否為null,如果為null將該Entry賦給correctEntry,迭代結束 * 3.如果待刪除的key不為null,操作同步驟2 * 4.如果correctEntry為null,函式直接返回null * 5.如果correctEntry不為Null,將待刪除的Entry值返回,並呼叫Set的remove方法刪除該Entry */ public V remove(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); Entry<K,V> correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) correctEntry = e; } } else { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) correctEntry = e; } } V oldValue = null; if (correctEntry !=null) { oldValue = correctEntry.getValue(); i.remove(); } return oldValue; }
4.查詢方法(Query Operations)
/** * 功能:返回map元素個數 * 實現: * 1.entrySet方法返回的是Set集合,呼叫Set集合的size方法獲取鍵值對的個數 */ public int size() { return entrySet().size(); } /** * 功能:該map集合是否為空 * 實現: * 1.通過判斷集合元素個數size是否為0即可判斷是否為空 */ public boolean isEmpty() { return size() == 0; } /** * 功能:判斷集合是否包含指定值 * 功能: * 1.獲取鍵值對的Set集合 * 2.如果指定元素為null,使用Set迭代器遍歷集合比較 * 3.如果指定元素不為null,使用Set迭代器遍歷集合比較 * 4.如果沒有找到返回false */ public boolean containsValue(Object value) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (value==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getValue()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (value.equals(e.getValue())) return true; } } return false; } /** * 功能:判斷集合是否包含指定鍵 * 實現:同上一個方法 */ public boolean containsKey(Object key) { Iterator<Map.Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return true; } } return false; } /** * 功能:根據鍵獲取值 * 實現: * 1.獲取鍵值對的Set集合 * 2.如果指定的key為null,遍歷集合,如果找到為null的key,則返回key * 3.如果指定的key不為空,遍歷集合,如果找到key,則返回key * 4.如果沒找到,則返回null */ public V get(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return e.getValue(); } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return e.getValue(); } } return null; }
5.批量操作(Bulk Operations)
/**
* 功能:新增一個map集合的元素到該集合中
* 實現:
* 1.使用增強for遍歷該map的集合,使用put方法逐個新增
*/
public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
6.檢視
/**
* 功能:返回鍵的Set集合
* 實現:
* 1.將keySet的地址應用賦給ks
* 2.如果ks沒有為null(沒有初始化),建立AbstractSet的子類並對其中的方法進行實現,獲取到entrySet()
* 的迭代器,就等同於獲取到他的所有元素;
* 3.返回ks
*
* 注:
* 1.這個方法的主體功能在呼叫的第一次會對keySet進行初始化,以後再次呼叫將不會執行主方法體,
* 直接返回keySet。
* 2.獲取到一個結合迭代器在一定程度上就等同於獲取到集合所有元素
*/
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new AbstractSet<K>() {
public Iterator<K> iterator() {
return new Iterator<K>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public K next() {
return i.next().getKey();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object k) {
return AbstractMap.this.containsKey(k);
}
};
keySet = ks;
}
return ks;
}
/**
* 功能:獲取所有的值,並以Collection集合的形式返回
* 實現:原理同keySet方法
*/
public Collection<V> values() {
Collection<V> vals = values;
if (vals == null) {
vals = new AbstractCollection<V>() {
public Iterator<V> iterator() {
return new Iterator<V>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
values = vals;
}
return vals;
}
7.核心方法
public abstract Set<Entry<K,V>> entrySet();
8.比較和雜湊(Comparison and hashing)
/**
* 功能:比較是否相等
* 實現:
* 1.如果o是本集合,則返回true
* 2.如果o資料型別不是map,則返回false
* 3.使用泛型萬用字元,將o轉換成m
* 4.獲取本集合的Entry迭代器
* 5.進行迭代分兩種情況比較
*/
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size())
return false;
try {
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}
/**
* 功能:返回次map集合的雜湊值
* 實現:
* 1.遍歷迭代每一個Entry,並將每個Entry的雜湊值相加求和並返回
*/
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
9.其他方法
/**
* 功能:將map集合以字串表示
* 實現:一看就能懂
*/
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
/**
* 功能:淺度克隆該map集合
* 注:不克隆鍵和值的集合
*/
protected Object clone() throws CloneNotSupportedException {
AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
四、兩個實現了Entry介面的靜態方法
這兩個方法分別為SimpleEntry靜態類和SimpleImmutableEntry靜態類。這兩個類的程式碼有99%都是相同的。只有setValue是不同的,SimpleEntry支援setValue功能而SimpleImmutableEntry不支援setValue方法,這也是這兩個類的主要區別,即SimpleEntry是執行緒不安全的Entry的實現而SimpleImmutableEntry是執行緒安全的Entry的實現.
/**
* Map介面的Entry實現類
*/
public static class SimpleEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
private static final long serialVersionUID = -8499721149061103585L;
// key值
private final K key;
// value值
private V value;
/**
* 功能:構造方法
*/
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
/**
* 功能:構造方法
*/
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
/**
* 功能:獲取鍵
*/
public K getKey() {
return key;
}
/**
* 功能:獲取值
*/
public V getValue() {
return value;
}
/**
* 功能:設定值並返回以前的值
*/
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
/**
* 功能:比較兩個Entry是否相等
*/
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
/**
* 功能:返回此SimpleEntry的雜湊值
* 注:^ 為異或運算子
*/
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
/**
* 功能:返回此SimpleEntry的字串表示
*/
public String toString() {
return key + "=" + value;
}
}
public static class SimpleImmutableEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
private static final long serialVersionUID = 7138329143949025153L;
private final K key;
private final V value;
/**
* 功能:構造方法
*/
public SimpleImmutableEntry(K key, V value) {
this.key = key;
this.value = value;
}
/**
* 功能:構造方法
*/
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
/**
* 功能:獲取鍵
*/
public K getKey() {
return key;
}
/**
* 功能:獲取值
*/
public V getValue() {
return value;
}
/**
* 功能:設定值
* 注:此方法,為了保證執行緒安全,此類不實現
*/
public V setValue(V value) {
throw new UnsupportedOperationException();
}
/**
* 功能:比較兩個Entry是否相等
*/
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
/**
* 功能:返回此SimpleEntry的雜湊值
* 注:^ 為異或運算子
*/
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
/**
* 功能:返回此SimpleEntry的字串表示
*/
public String toString() {
return key + "=" + value;
}
}
五、總結
AbstractMap抽象類提供Map介面的骨幹實現,以最大限度地減少實現此介面所需的工作量。
此類中有兩個Map介面中Entry介面的靜態實現,SimpleEntry類和SimpleImmutableEntry。SimpleEntry是執行緒安全的,SimpleImmutableEntry是執行緒不安全的。