package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
//Map接口,散列表接口的父接口,每一个元素对象都是{key:value}组成
public interface Map<K, V> {
    // Query Operations+
    int size();
    boolean isEmpty();
    boolean containsKey(Object key);//是否含有key
    boolean containsValue(Object value);//是否含有value
    V get(Object key);//通过key返回对应的value,如果key不存在,会抛异常
    // 修改方法
    V put(K key, V value);//将{key:value}放入到散列表中,如果key已经存在,则覆盖
    V remove(Object key);//如果散列表中含有key,则移除该该{key:value},并返回value
    // 扩展方法,同Collection
    void putAll(Map<? extends K, ? extends V> m);
    void clear();
    // 视图
    Set<K> keySet(); //返回 Map 集合中所有键对象的 Set 集合
    Collection<V> values();//values构成的集合
    Set<Map.Entry<K, V>> entrySet();//返回Map集合中所有键-值对的 Set 集合,此 Set 集合中元素的数据类型为 Map.Entry
    //内部接口Entry
    interface Entry<K, V> {
        K getKey();
        V getValue();
        V setValue(V value);
        boolean equals(Object o);
        int hashCode();
        // 返回通过key进行比较的比较器Comparable对象
        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());
        }
        // 返回通过value进行比较的比较器Comparable对象
        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进行比较的比较器Comparator对象
        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());
        }
        // 返回通过value进行比较的比较器Comparator对象
        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();
    // Defaultable methods
    // 当map含有key,就返回对应的value。如果不含有key,则返回 defaultValue
    default V getOrDefault(Object key, V defaultValue){
        V v;
        return (((v = get(key)) != null) || containsKey(key))
                ? v
                : defaultValue;
    }
    // 通过操作型函数接口,对map每一个元素遍历操作
    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);//函数接口操作k-v键值对
        }
    }
    // 通过操作型函数接口,对替换map中的每一个value
    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); //函数接口替换 value

            try {
                entry.setValue(v);
            } catch (IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
        }
    }
    // 如果一个key对应的value==null,则为他赋值value,并返回value
    default V putIfAbsent(K key, V value){
        V v = get(key);
        if(v == null){
            v = put(key, value);
        }

        return v;
    }

    //  移除指定 key-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;
    }

    //  替换指定 key-value的键值,key和value都相等才替换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存在,直接替换为value
    default V replace(K key, V value){
        V curValue;
        if(((curValue = get(key)) != null) || containsKey(key)){
            curValue = put(key, value);
        }
        return curValue;
    }

    // 如果key存在且value为null,则通过函数接口计算value,返回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存在且value不为null,则通过函数接口计算新value,如果新value不为null,替换旧value
    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存在且value不为null,则通过函数接口计算新value,如果新value不为null,替换旧value,如果为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;
        }
    }
    // 如果旧value==null,则旧value赋值为输入value
    // 通过映射函数接口将map中的旧value映射到新值
    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;
    }
}