java源碼分析之集合框架AbstractMap 08
來源:程序員人生 發(fā)布時間:2016-12-08 17:32:30 閱讀次數(shù):2432次
AbstractMap:

AbstractMap
AbstractMap繼承了Map,但沒有實現(xiàn)entrySet()方法(該方法還是abstract修飾),如果要繼承AbstractMap,需要自己實現(xiàn)entrySet()方法。沒有真正實現(xiàn)put(K key, V value)方法,這里“沒有真正實現(xiàn)”的意思是,該方法在情勢上已實現(xiàn)了,即沒有用abstract修飾了,但是方法內(nèi)部僅僅是拋出個異常,并沒有真正實現(xiàn)方法體內(nèi)容,從下面的源碼中可以看到。
此類提供 Map 接口的骨干實現(xiàn),以最大限度地減少實現(xiàn)此接口所需的工作。
要實現(xiàn)不可修改的映照,編程人員只需擴大此類并提供 entrySet 方法的實現(xiàn)便可,該方法將返回映照的映照關(guān)系 set 視圖。通常,返回的 set 將順次在AbstractSet 上實現(xiàn)。此 set 不支持add 或
remove 方法,其迭代器也不支持 remove 方法。
要實現(xiàn)可修改的映照,編程人員必須另外重寫此類的 put 方法(否則將拋出 UnsupportedOperationException),entrySet().iterator() 返回的迭代器也必須另外實現(xiàn)其remove 方法。
依照 Map 接口規(guī)范中的建議,編程人員通常應(yīng)當(dāng)提供1個 void(無參數(shù))構(gòu)造方法和 map 構(gòu)造方法。
此類中每一個非抽象方法的文檔詳細(xì)描寫了其實現(xiàn)。如果要實現(xiàn)的映照允許更有效的實現(xiàn),則可以重寫所有這些方法
public abstract class AbstractMap<K,V> implements Map<K,V>
AbstractMap源碼:
//抽象類
public abstract class AbstractMap<K,V> implements Map<K,V> {
/**
* 空構(gòu)造函數(shù)
*/
protected AbstractMap() {
}
/*----------查詢操作--------------------*/
public int size() {
return entrySet().size();
}
public boolean isEmpty() {
return size() == 0;
}
// 如果此映照將1個或多個鍵映照到指定值,則返回 true。
public boolean containsValue(Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();//entrySet要自己實現(xiàn)
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;
}
//如果此映照包括指定鍵的映照關(guān)系,則返回 true。
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;
}
//返回指定鍵所映照的值;如果此映照不包括該鍵的映照關(guān)系,則返回 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) //AbstractMap 的鍵值對可以為NULL
return e.getValue();
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return e.getValue();
}
}
return null;
}
/*----------修改操作--------------------*/
//將指定的值與此映照中的指定鍵關(guān)聯(lián)
//要實現(xiàn)可修改的映照,必須另外重寫此類的 put 方法
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
//如果存在1個鍵的映照關(guān)系,則將其從此映照中移除
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;
}
/*----------容量操作--------------------*/
public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
public void clear() {
entrySet().clear();
}
/*----------視圖--------------------*/
transient volatile Set<K> keySet = null;
transient volatile Collection<V> values = null;
public Set<K> keySet() {
if (keySet == null) {
keySet = 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);
}
};
}
return keySet;
}
public Collection<V> values() {
if (values == null) {
values = 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);
}
};
}
return values;
}
public abstract Set<Entry<K,V>> entrySet();
/*----------比較和散列-------------------*/
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<K,V> m = (Map<K,V>) 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<K,V>的hash值為每一個映照的hash總和
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
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(' ');
}
}
//返回此 AbstractMap 實例的淺表副本:不復(fù)制鍵和值本身。
protected Object clone() throws CloneNotSupportedException {
AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
private static boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
/*SimpleEntry實現(xiàn)了Map類中的Entry接口,
另外也實現(xiàn)了Serializable接口,可序列化
*/
public static class SimpleEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
private static final long serialVersionUID = ⑻499721149061103585L;
private final K key;
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;
}
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());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
}
/*SimpleEntry實現(xiàn)了Map類中的Entry接口,
另外也實現(xiàn)了Serializable接口,可序列化
*/
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();
}
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());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
//重寫了toString方法,返回key=value情勢
public String toString() {
return key + "=" + value;
}
}
}
從源碼中可以看出,AbstractMap類提供了Map接口的主要實現(xiàn),以最大限度地減少了實現(xiàn)此接口所需的工作,但是AbstractMap沒有實現(xiàn)entrySet()方法。所以如果我們要實現(xiàn)不可修改的Map時,只需要擴大此類并提供entrySet()方法的實現(xiàn)便可,另外從源碼中也能夠看出,entrySet()方法返回的Set(即keySet)不支持add()或remove()方法。如果我們要實現(xiàn)可修改的Map,那末就必須另外重寫put()方法,否則將拋出UnsupportedOperationException,而且entrySet.iterator()返回的迭代器i也必須實現(xiàn)其remove方法。
不過1般我們不需要自己實現(xiàn)Map,由于已有Map的實現(xiàn)類了,如HashMap和TreeMap等。
AbstractMap 結(jié)構(gòu):

其中:SimpleImmutableEntry<K,V>和SimpleEntry<K,V>兩個嵌套類會在AbstractMap的子類中用到
public static class SimpleEntry<K,V>
implements Entry<K,V>, java.io.Serializable
public static class SimpleImmutableEntry<K,V>
implements Entry<K,V>, java.io.Serializable
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈