JAVA知识梳理三(MAP)

  • 首先,map是一个顶级接口,不是那么重要,其源码里也写了,相关代码还需要了解:
 * @author  Josh Bloch
 * @see HashMap
 * @see TreeMap
 * @see Hashtable
 * @see SortedMap
 * @see Collection
 * @see Set
 
  • 然后,请记住以下:

1.将键映射到值的对象。映射不能包含重复的键;每个键最多可以映射到一个值。
2.这个接口取代了java的字典类(java的字典类我感觉和python的字典有点像的,有兴趣可以了解下)
3.map接口提供了三个集合视图

key集合
value集合
key_value集合
4.map是根据hashCode和equals方法决定存放的位置的,个特殊的案例是不允许一个map将自己作为一个key,但允许将自己作为一value。
5.所有多种用途的map实现类应该提供两个“标准”构造器,一个无参构造器用来创建一个空map,一个只有一个参数,参数类型是map的构造器,用来创建一个新的和传入参数有一样key-value映射的map。实际上,后者允许复制任何一个map,这仅仅是一个建议,并没有强制要求,因为接口是无法包含构造器的,不过这个建议在JDK被遵守。
6.map报错异常一般为UnsupportedOperationException,但是空指针异常除外.

  • 上代码


package java.util;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;

//关于map的描述上边已经讲清楚了,不再重复
public interface Map<K,V> {
   //返回映射中键值映射数,如果map包含的值大于integer.max_value,返回integer.max_value。
   int size();

   //判断是否为空
   boolean isEmpty();

   //如果map不含key映射,返回false,当key的类型不符合,抛出ClassCastException,当key是null且该map不支持key的值是null时,抛出空指针异常
   boolean containsKey(Object key);
   如果map含有一个以上的key映射的参数value,返回true,异常抛出的情况和containKey一样
   boolean containsValue(Object value);

   //输入key值获取value,如果没有对应的映射,返回null,如果map允许value为null(HashMap key值均允许为null)
   V get(Object key);

  //往map放入一对key-value映射
   V put(K key, V value);
   
   //根据key删除对应映射
   V remove(Object key);
  
  //复制一份参数一样的map
   void putAll(Map<? extends K, ? extends V> m);
  //清空map中所有的映射(暂时没有想到使用场景,如果要覆盖new一个不好吗)
   void clear();

   //返回map中所有key的集合
   Set<K> keySet();

  //返回map中所有value的集合
   Collection<V> values();

   //返回key-value的集合
   Set<Map.Entry<K, V>> entrySet();

   //map的一个内部接口,相当于map数据模型
   interface Entry<K,V> {
   	//返回对应的key
       K getKey();

   	//返回对应的value
       V getValue();

   	//设置用新value替换旧value,返回值是旧value
       V setValue(V value);

   	//如果两个entry的映射一样,返回true
       boolean equals(Object o);

   	//计算entry的hash code
       int hashCode();
   	//返回一个比较器,比较的规则是key的自然大小(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());
       }
   	//返回一个比较器,比较规则是value的自然大小
       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());
       }

   	//返回一个比较器,比较规则用参数传入,比较的是value
       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);
   //计算hash值
   int hashCode();


   //default关键字有兴趣可以了解一下,蛮有意思的


   //只要 map.keySet() 中含有该 key, 就会返回对应的 value, 即使 value == null
   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);
       }
   }

   //.replaceAll使用了可以传递3个参数的内置的函数式接口BiFunction,其方法apply方法可以返回一个继承至V的值,可以看到这个方法时通过function处理K,V之后,处理方法是针对其父类的(? super K),然后得到新的值赋值给之前的key.
   //将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或函数引发异常为止
   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);
           }
       }
   }

   //与put方法非常类似但是如果指定的键未与某个值关联(或映射到null),则将其与给定值关联并返回null,否则返回当前值。 
   //默认的实现对该方法的同步或原子性质没有保证。提供原子性的保证任何的实现必须重写此方法和文件的并发性能。
   default V putIfAbsent(K key, V value) {
       V v = get(key);
       if (v == null) {
           v = put(key, value);
       }

       return v;
   }
   //只有 key:value 与 map 中的 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;
   }
   //replace(k,v)直接替换,返回当前值;
   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;
   }
   //replace(k,v1,v2)只在当key,value都对应的时候,才会进行替换
   default V replace(K key, V value) {
       V curValue;
       if (((curValue = get(key)) != null) || containsKey(key)) {
           curValue = put(key, value);
       }
       return curValue;
   }
   //利用函数计算的结果,作为value替换或者新增 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;
   }

    /**
        * 当get(key)不为null时,新value替换旧的value, 返回旧值; 反之,删除key直接返回 null
        */
   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;
       }
   }
   //当get(key)为null时,value新增或者替换旧的map.entry(k,v)
   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;
       }
   }
   
   //当get(key)不为null时,以get(key), v 作为参数计算返回结果,如果结果为null,则remove(k),反之则替换旧值
   // 当get(key)为 null 时,直接用 v 进行替换
   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;
   }
}


版权声明:本文为weixin_43866244原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。