java集合類源碼分析(五):Map接口

我的github:xjwhhh的github
希望大家多多關注,共同進步

Java集合類源碼分析(一):Collcetion接口
Java集合類源碼分析(二):List接口
Java集合類源碼分析(三):AbstractList類
Java集合類源碼分析(四):ArrayList&LinkedList
java集合類源碼分析(五):Map接口
Java集合類源碼分析(六):AbstractMap類
Java集合類源碼分析(七):HashMap&LinkedHashMap
Java集合類源碼分析(八):AbstractSet類
Java集合類源碼分析(九):HashSet&LinkedHashSet

Map接口源碼解析

Map接口的順序與迭代器在集合角度上的順序相同,有三種集合角度,分別是鍵的set,值的集合,和鍵值對的mappings

一些實現類,如TreeMap,對於順序做了一些保證,另一些例如HashMap就沒有

map不能以map做鍵,能以map做值,但這樣的map對於equals和hashCode方法定義的不好

void putAll(Map<? extends K, ? extends V> m);

將參數map中的所有鍵值對放入原map中。如果在執行操作的過程中參數map被改變了,該操作就是undefined

Set<Map.Entry<K, V>> entrySet();

將map中的鍵值對以set的形式返回,map中的改變會在set中體現出來,反過來也是

如果在用迭代器遍歷該set時,map發生了改變(除了使用iterator.remove或者用迭代器對map entry的setValue),該迭代就是undefined

這個set支持Iterator.remove,Set.remove,removeAll,retainAll,clear,不支持add和addAll

interface Entry<K,V>{......}

定義了Map.Entry的操作

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

如果map含有參數key這樣的鍵,就返回對應的值,否則返回參數defaultValue

default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        action.accept(k, v);
    }
}

使用迭代器遍歷map,對於每一個鍵值對,進行action操作

default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
    Objects.requireNonNull(function);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }

        // ise thrown from function is not a cme.
        v = function.apply(k, v);

        try {
            entry.setValue(v);
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
    }
}

使用迭代器遍歷map,對於每個鍵值對,對值進行操作並更新

default V putIfAbsent(K key, V value) {
    V v = get(key);
    if (v == null) {
        v = put(key, value);
    }

    return v;
}

如果參數key並沒有對應的值,或者對應的是null,就將之與參數value對應起來,返回key此時對應的value

default boolean remove(Object key, Object value) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, value) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    remove(key);
    return true;
}

如果map中含有與參數一致的鍵值對,就將之刪除,返回true,否則返回false

default boolean replace(K key, V oldValue, V newValue) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, oldValue) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    put(key, newValue);
    return true;
}

如果map中含有與key-oldValue一致的鍵值對,就將值更新爲newValue

default V replace(K key, V value) {
    V curValue;
    if (((curValue = get(key)) != null) || containsKey(key)) {
        curValue = put(key, value);
    }
    return curValue;
}

如果map有相應的key,就更新它的值爲value

default V computeIfAbsent(K key,
        Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
        V newValue;
        if ((newValue = mappingFunction.apply(key)) != null) {
            put(key, newValue);
            return newValue;
        }
    }

    return v;
}

如果參數key並沒有與某個值對應或者對應的是null,嘗試通過給定的參數函數計算出值並與key對應

default V computeIfPresent(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null) {
            put(key, newValue);
            return newValue;
        } else {
            remove(key);
            return null;
        }
    } else {
        return null;
    }
}

如果參數key有與之對應的值,嘗試通過給定的參數函數計算出值並與key對應

default V compute(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue = get(key);

    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue == null) {
        // delete mapping
        if (oldValue != null || containsKey(key)) {
            // something to remove
            remove(key);
            return null;
        } else {
            // nothing to do. Leave things as they were.
            return null;
        }
    } else {
        // add or replace old mapping
        put(key, newValue);
        return newValue;
    }
}

對於參數key和它對應的值,用函數計算出新的值,並進行替換

default V merge(K key, V value,
        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
               remappingFunction.apply(oldValue, value);
    if(newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

如果參數key並沒有與某個值對應或者對應的是null,就將key與給定的參數value對應,否則就用給定參數函數計算出新值並進行更新

發佈了43 篇原創文章 · 獲贊 27 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章