Java集合之Map

时间:2021-05-08 12:40:47
Map架构:
Java集合之Map
Java集合之Map
如上图:
(1)Map是映射接口,Map中存储的内容是键值对(key-value)
(2)AbstractMap是继承于Map的抽象类,实现了Map中的大部分API。
(3)SortedMap是继承于Map的接口,SortedMap中的内容是排序的键值对,排序的方法是通过比较器。
(4)NavigableMap继承于SortedMap,其中有一系列的导航方法,如“获取大于或等于某对象的键值对”等等
(5)TreeMap继承于AbstractMap和NavigableMap接口,因此TreeMap中的内容是有序的键值对。
(6)HashMap继承于AbstractMap,内容也是键值对,但不保证次序。
(7)WeakHashMap继承于AbstractMap,它和HashMap的键类型不同,WeakHashMap是弱键。
(8)HashTable继承于Directionary同时也实现了Map,因此是键值对的,但不保证次序,同时是线程安全的。
总结:
HashMap是基于”拉链法“实现的散列表,一般用于单线程,键值都可以为空,支持Iterator(迭代器)遍历
Hashtable是基于”拉链法“实现的散列表,是线程安全的,可以用于多线程程序中。支持Iterator(迭代器)遍历和Enumeration(枚举器)两种遍历方式。
WeakHashMap也是基于”拉链法“实现的散列表,同时是弱键
TreeMap 是有序的散列表,通过红黑树来实现的,键值都不能为空。

Java8的Map接口的源码:


public interface Map<K,V> {
    int size();//数目
    boolean isEmpty();//判断是否为空
    boolean containsKey(Object key);//判断是否含有某个key
    boolean containsValue(Object value);//判断是否含有某个值
    V get(Object key);//通过key获得value
    V put(K key, V value);//插入键值对
    V remove(Object key);//通过key删除
    void putAll(Map<? extends K, ? extends V> m);//将一个Map插入
    void clear();//清空
    Set<K> keySet();//返回key集合
    Collection<V> values();//返回value
    Set<Map.Entry<K, V>> entrySet();//实体集合,Map的改变会影响到它
    interface Entry<K,V> {
        K getKey();//获得key
        V getValue();//获得value
        V setValue(V value);//设置值
        boolean equals(Object o);//判断对象是否相等
        int hashCode();//返回hashCode
        //比较器,比较两个key
        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());
        }
        //比较两个值
        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                    (c1, c2) -> c1.getValue().compareTo(c2.getValue());
        }
        //比较两个key
        public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                    (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
        }
        //比较两个值
        public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                    (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
        }
    }
    //比较map是否相等
    boolean equals(Object o);
    int hashCode();//hashCode
    default V getOrDefault(Object key, V defaultValue) {
        V v;
        return (((v = get(key)) != null) || containsKey(key))
                ? v
                : 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);
        }
    }
    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);
            }
        }
    }
    default V putIfAbsent(K key, V value) {
        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }

        return v;
    }
    //删除某个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;
    }
    //将某个key和oldValue对应的值替换为newValue
    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;
    }
    //替换key的值
    default V replace(K key, V value) {
        V curValue;
        if (((curValue = get(key)) != null) || containsKey(key)) {
            curValue = put(key, value);
        }
        return curValue;
    }
    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;
    }
    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;
        }
    }
    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;
        }
    }
    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;
    }
}