Java-Collection源码分析(六)——Map接口

一、Map的集合框架

二、Map接口

将键映射到值的对象。map不能包含重复的键;每个键可以映射到最多一个值。该接口取代了Dictionary类,Dictionary是一个完全抽象的类而不是接口。Map接口提供三个集合视图,允许将映射内容视为一组键、值集合或者是键值映射集合。map的顺序被定义为地图集合视图上的迭代器返回其元素的顺序。一些map实现,对其顺序做出特定的保证,如TreeMap类;其他的则不需要,如HashMap类。

public interface Map<K,V> {
    // Query Operations
    int size();
    boolean isEmpty();
    boolean containsKey(Object key);
    boolean containsValue(Object value);
    V get(Object key);
    V put(K key, V value);
    V remove(Object key);
    void putAll(Map<? extends K, ? extends V> m);
    void clear();
    Set<K> keySet();
    Collection<V> values();
    Set<Map.Entry<K, V>> entrySet();
    //Map是基于链表操作的,而每个元素存储的就是Entry。Map.entrySet方法返回地图的集合视图,其元素属于此类。 获取对映射条目的引用的唯一方法是从该集合视图的迭代器。 这些Map.Entry对象仅在迭代期间有效; 更正式地,如果在迭代器返回条目之后修改了背景映射,则映射条目的行为是未定义的,除了通过映射条目上的setValue操作。
    interface Entry<K,V> {
	//返回与此条目相对应的键。
        K getKey();
	//返回与该条目对应的值。
        V getValue();
	//用指定的值替换与该条目相对应的值(可选操作)。
        V setValue(V value);
	//将指定的对象与此条目进行比较以获得相等性。
        boolean equals(Object o);
	//返回此映射条目的哈希码值
        int hashCode();
	//返回一个比较器,它按键的自然顺序对Map.Entry进行比较。JDK1.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());
        }
	//返回一个比较器,以比较Map.Entry的自然顺序的值。JDK1.8
        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());
        }
	//返回一个比较器,它使用给定的比较器比较Map.Entry的键。JDK1.8
        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());
        }
	//返回一个比较器,它使用给定的比较器比较Map.Entry的值。JDK1.8
        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());
        }
    }
    boolean equals(Object o);
    int hashCode();
    //返回指定键映射到的值,如果此映射不包含键的映射,则返回defaultValue。JDK1.8
    default V getOrDefault(Object key, V defaultValue) {
        V v;
        return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue;
    }
    //对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。JDK1.8
    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) {
                throw new ConcurrentModificationException(ise);
            }
            v = function.apply(k, v);
            try {
                entry.setValue(v);
            } catch(IllegalStateException ise) {
                throw new ConcurrentModificationException(ise);
            }
        }
    }
    //如果指定的键还没有与值相关联(或映射到null)将其与给定值相关联并返回null,否则返回当前值。
    default V putIfAbsent(K key, V value) {
        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }
        return v;
    }
    //只有当目标映射到指定的值时,才能删除指定键的条目。
    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;
    }
    //仅当当前映射到指定的值时,才能替换指定键的条目。
    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;
    }
    //只有当目标映射到某个值时,才能替换指定键的条目。
    default V replace(K key, V value) {
        V curValue;
        if (((curValue = get(key)) != null) || containsKey(key)) {
            curValue = put(key, value);
        }
        return curValue;
    }
    //如果指定的键尚未与值相关联(或映射到null),则尝试使用给定的映射函数计算其值,并将其输入到此映射中,除非为null。
    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;
        }
    }
    //尝试计算指定密钥及其当前映射值的映射(如果没有当前映射,则为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;
        }
    }
    //如果指定的键尚未与值相关联或与null相关联,则将其与给定的非空值相关联。
    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;
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值