java.util.AbstractMap
()
構造方法/** * 惟一的構造器。(通常由子類隱式調用) */ protexted AbstractMap(){ }
size()
返回當前map的大小public int size() { return entrySet().size(); }
這裏的
entrySet()
返回一個Set<Entry<K,V>>
對象。可是當前類AbstractMap
沒有實現它。下同java
isEmpty()
判斷當前Map是否爲空public boolean isEmpty() { return size() == 0; }
containsKey(Object key)
是否包含指定keypublic 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; }
一樣依靠
entrySet()
方法,使用迭代器檢查每個Entry
的Key值
當參數key爲空時,有任何一個Entry的key值爲空則返回true
當參數key不爲空時,參數key的equals
方法與任何一個key返回true時本方法返回true
其餘狀況返回false緩存
get(Object key)
獲取指定valpublic 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; }
與
containsKey(Object key)
相同,返回值由bool變成了Entry
的getVale
的返回值
其餘狀況下,返回null
併發
public V put(K key, V value) { throw new UnsupportedOperationException(); }
直接拋出異常UnsupportedOperationExceptionthis
remove(Object key)
刪除指定鍵值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; }
基於
entrySet()
,獲取到對應Entry
後,緩存其val,並在迭代器中刪除找到的Entry
,而後返回valcode
putAll(Map<? extends K, ? extends V> m)
添加指定Map中的鍵值對到當前當前Map中public void putAll(Map<? extends K, ? extends V> m) { for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue()); }
基於
entrySet()
,迭代調用put(K key, V value)
方法進行操做
本類中put(K key, V value)
的實現爲直接拋出UnsupportedOperationException()
異常對象
public void clear() { entrySet().clear(); }
直接清空
entrySet()
所返回的Set
集合rem
keySet
與values
transient Set<K> keySet; transient Collection<V> values;
這兩個變量主要用於
keySet()
與values()
方法。get
Set<K> keySet()
獲取key
集合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; }
此方法會初始化成員變量
keySet
並保持它的單例(由於沒有作同步處理,因此有可能在併發環境下返回不一樣的對象)。
此方法構造的Set
集合實際類型爲AbstractSet
的匿名內部類,主要有以下實現同步
iterator()
方法的實現每次構造一個新的Iterator
對象,並在內部保存外部類的entrySet()
的iterator()
方法所返回的迭代器對象。做爲委派目標i
- 新的Iterator對象的
hasNext()
,next()
,remove()
方法均委託到變量i
AbstractSet
其餘的實現方法size()
,isEmpty()
,clear()
,contains(Object k)
所有委託到外部類AbstractMap
的同名方法這裏發生了一次數據上的可能的分離,就是
iterator()
所返回對象內部對象i
來自entrySet().iterator()
,而此時其餘的方法如size()
使用的實際方法爲entrySet().size()
,有可能會發生數據不一樣步的狀況hash
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; }
與
keySet()
相同,只是返回類型換爲容許重複元素的AbstractCollection
equals(Object o)
比較兩個Map
是否相同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; }
比較流程以下
- 若是是同一個對象,則返回
true
- 若是入參不是
Map
的子類,直接返回false
- 若是二者的
size()
返回的數量不一樣,直接返回false
- 使用
entrySet().iterator()
獲取當前對象的迭代器並進行迭代。進行以下操做- 迭代中。當val爲空時,使用key向入參map進行值獲取,結果值不爲空或不包含這個key時,返回
false
- 迭代中。當val爲不空時,使用key向入參map進行值獲取,當使用
equals
比較二者不相同時,返回false
- 迭代中出現
ClassCastException
與NullPointerException
返回false
- 執行到結尾,返回
true
hashCode()
獲取HashCodepublic int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; }
迭代全部
Entry
,累加全部Entry
的HashCode
clone()
clone當前對象protected Object clone() throws CloneNotSupportedException { AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone(); result.keySet = null; result.values = null; return result; }
注意,這裏是淺拷貝,並對新對象的
keySet
與values
屬性進行置空
因爲當前抽象類的絕大多數實現是基於方法entrySet()
方法,因此這個方法須要由實現類進行關注。防止淺拷貝後,新對象指向老引用引起問題