Java集合源碼分析之Map(一):超級接口Map_一點課堂(多岸學院)

數組與鏈表在處理數據時各有優缺點,數組查詢速度很快而插入很慢,鏈表在插入時表現優秀但查詢無力。哈希表則整合了數組與鏈表的優勢,能在插入和查找等方面都有不錯的速度。咱們以後要分析的HashMap就是基於哈希表實現的,不過在JDK1.8中還引入了紅黑樹,其性能進一步提高了。本文主要分析JDK中關於Map的定義。java

接口Map

Map的定義爲:數組

An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.性能

也就是基於key-value的數據格式,而且key值不能夠重複,每一個key對應的value惟一。Map的key也能夠爲null,也不可重。學習

在分析其定義的方法前,咱們要先了解一下Map.Entry這個接口。this

接口Map.Entry

存儲在Map中的數據須要實現此接口,主要提供對key和value的操做,也是咱們使用最多的操做。咱們先分析它:code

// 獲取對應的key
K getKey();

// 獲取對應的value
V getValue();

// 替換原有的value
V setValue(V value);

// 但願咱們實現equals和hashCode
boolean equals(Object o);
int hashCode();

// 從1.8起,還提供了比較的方法,相似的方法共四個
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
        return (Comparator<Map.Entry<K, V>> & Serializable)
            (c1, c2) -> c1.getKey().compareTo(c2.getKey());
}

重要方法

// 返回當前數據個數
int size();

// 是否爲空
boolean isEmpty();

// 判斷是否包含key,這裏用到了key的equals方法,因此key必須實現它
boolean containsKey(Object key);

// 判斷是否有key保存的值是value,這也基於equals方法
boolean containsValue(Object value);

// 經過key獲取對應的value值
V get(Object key);

// 存入key-value
V put(K key, V value);

// 移除一個key-value對
V remove(Object key);

// 從其餘Map添加
void putAll(Map<? extends K, ? extends V> m);

// 清空
void clear();

// 返回全部的key至Set集合中,由於key是不可重的,Set也是不可重的
Set<K> keySet();

// 返回全部的values
Collection<V> values();

// 返回key-value對到Set中
Set<Map.Entry<K, V>> entrySet();

// 但願咱們實現equals和hashCode
boolean equals(Object o);
int hashCode();

此外,還有一些Java8相關的default方法,就不一一展現了。blog

default V getOrDefault(Object key, V defaultValue) {
    V v;
    return (((v = get(key)) != null) || containsKey(key))
        ? v
        : defaultValue;
}

超級實現類:AbstractMap

對應於AbstractCollectionAbstractMap的做用也是相似的,主要是提供一些方法的實現,能夠方便繼承。下面咱們看看它都實現了哪些方法:繼承

// 返回大小,這裏大小基於entrySet的大小
public int size() {
    return entrySet().size();
}

public boolean isEmpty() {
    return size() == 0;
}

//基於entrySet操做
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;
    }

public boolean containsValue(Object value) {
    //...
}

public V get(Object key) {
    //...
}

public V remove(Object key) {
    //...
}

public void clear() {
    entrySet().clear();
}

除此之外,還定義了兩個變量:接口

transient Set<K>        keySet;
transient Collection<V> values;

還提供了默認的實現方法,咱們只看其中一個吧:圖片

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;
}

除了以上相關方法之外,AbstractMap還實現了equalshashCodetoStringclone等方法,這樣在具體實現時能夠省去不少工做。


【感謝您能看完,若是可以幫到您,麻煩點個贊~】

更多經驗技術歡迎前來共同窗習交流: 一點課堂-爲夢想而奮鬥的在線學習平臺 http://www.yidiankt.com/

![關注公衆號,回覆「1」免費領取-【java核心知識點】] file

QQ討論羣:616683098

QQ:3184402434

想要深刻學習的同窗們能夠加我QQ一塊兒學習討論~還有全套資源分享,經驗探討,等你哦! 在這裏插入圖片描述

相關文章
相關標籤/搜索