中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Map大家族的那點事兒(2) :AbstractMap

2018-09-04    來源:importnew

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

AbstractMap


AbstractMap是一個抽象類,它是Map接口的一個骨架實現(xiàn),最小化實現(xiàn)了此接口提供的抽象函數(shù)。在Java的Collection框架中基本都遵循了這一規(guī)定,骨架實現(xiàn)在接口與實現(xiàn)類之間構(gòu)建了一層抽象,其目的是為了復(fù)用一些比較通用的函數(shù)以及方便擴展,例如List接口擁有骨架實現(xiàn)AbstractList、Set接口擁有骨架實現(xiàn)AbstractSet等。

下面我們按照不同的操作類型來看看AbstractMap都實現(xiàn)了什么,首先是查詢操作:

package java.util;
import java.util.Map.Entry;
public abstract class AbstractMap<K,V> implements Map<K,V> {

    protected AbstractMap() {
    }
    // Query Operations
    public int size() {
        return entrySet().size();
    }
    // 鍵值對的集合視圖留給具體的實現(xiàn)類實現(xiàn)
    public abstract Set<Entry<K,V>> entrySet();
    public boolean isEmpty() {
        return size() == 0;
    }
    /**
     * 遍歷entrySet,然后逐個進行比較。
     */
    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;
    }
    /**
     * 跟containsValue()同理,只不過比較的是key。
     */
    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;
    }
    /**
     * 遍歷entrySet,然后根據(jù)key取出關(guān)聯(lián)的value。
     */
    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;
    }
}

可以發(fā)現(xiàn)這些操作都是依賴于函數(shù)entrySet()的,它返回了一個鍵值對的集合視圖,由于不同的實現(xiàn)子類的Entry實現(xiàn)可能也是不同的,所以一般是在內(nèi)部實現(xiàn)一個繼承于AbstractSet且泛型為Map.Entry的內(nèi)部類作為EntrySet,接下來是修改操作與批量操作:

// Modification Operations
/**
 * 沒有提供實現(xiàn),子類必須重寫該方法,否則調(diào)用put()會拋出異常。
 */
public V put(K key, V value) {
    throw new UnsupportedOperationException();
}
/**
 * 遍歷entrySet,先找到目標(biāo)的entry,然后刪除。
 *(還記得之前說過的嗎,集合視圖中的操作也會影響到實際數(shù)據(jù))
 */
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;
}
// Bulk Operations
/**
 * 遍歷參數(shù)m,然后將每一個鍵值對put到該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等價于清空該Map。
 */
public void clear() {
    entrySet().clear();
}

AbstractMap并沒有實現(xiàn)put()函數(shù),這樣做是為了考慮到也許會有不可修改的Map實現(xiàn)子類繼承它,而對于一個可修改的Map實現(xiàn)子類則必須重寫put()函數(shù)。

AbstractMap沒有提供entrySet()的實現(xiàn),但是卻提供了keySet()values()集合視圖的默認(rèn)實現(xiàn),它們都是依賴于entrySet()返回的集合視圖實現(xiàn)的,源碼如下:

/**
 * keySet和values是lazy的,它們只會在第一次請求視圖時進行初始化,
 * 而且它們是無狀態(tài)的,所以只需要一個實例(初始化一次)。
 */
transient Set<K>        keySet;
transient Collection<V> values;
/**
 * 返回一個AbstractSet的子類,可以發(fā)現(xiàn)它的行為都委托給了entrySet返回的集合視圖
 * 與當(dāng)前的AbstractMap實例,所以說它自身是無狀態(tài)的。
 */
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()基本一致,唯一的區(qū)別就是返回的是AbstractCollection的子類,
 * 主要是因為value不需要保持互異性。
 */
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;
}

它還提供了兩個Entry的實現(xiàn)類:SimpleEntry與SimpleImmutableEntry,這兩個類的實現(xiàn)非常簡單,區(qū)別也只是前者是可變的,而后者是不可變的。

private static boolean eq(Object o1, Object o2) {
    return o1 == null ? o2 == null : o1.equals(o2);
}
public static class SimpleEntry<K,V>
    implements Entry<K,V>, java.io.Serializable
{
    private static final long serialVersionUID = -8499721149061103585L;
    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的區(qū)別在于它是不可變的,value被final修飾,并且不支持setValue()。
 */
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());
    }
    public String toString() {
        return key + "=" + value;
    }
}

我們通過閱讀上述的源碼不難發(fā)現(xiàn),AbstractMap實現(xiàn)的操作都依賴于entrySet()所返回的集合視圖。剩下的函數(shù)就沒什么好說的了,有興趣的話可以自己去看看。

標(biāo)簽:

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:谷歌推出最新AngularJS升級工具,可快速遷移至Angular

下一篇:SpringBoot | 第十五章:基于Postman的RESTful接口測試