Java集合框架(十一):Map 源码分析 2022-04-23 23:26 258阅读 0赞 ### 文章目录 ### * * 1、Map 简述 * 2、Map 类图 * 3、Map 方法说明 ## 1、Map 简述 ## java.util.Map 接口表示键和值之间的映射对象。Map接口不是Collection接口的子类型。因此它的行为与其他集合类型略有不同。Map接口取代了传统的 Dictionary类,它是一个完全抽象的类而不是接口。 **Map 接口具有以下几个特征:** 1、Map提供了三个集合视图,键集,键值映射集和值集合。 2、Map 不能包含重复的键,每个键最多可以映射一个值。一些实现允许null键和null值,如HashMap和LinkedHashMap,但有些实现不允许,比如:TreeMap。 3、Map 的顺序取决于具体的实现,例如 TreeMap 和LinkedHashMap 保证了元素的顺序,而 HashMap 则没有。 4、Map 使用 hashCode 和equals 方法来获取和存放操作。 所以可变类不适合Map键。 如果 hashCode 或 equals 的值在put之后发生变化,则在get操作中将无法获得正确的值。 5、AbstractMap 类提供了 Map 接口的主要实现,大多数Map实现类扩展了 AbstractMap 类并实现了所需的方法。 6、当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常. 7、当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。 8、当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。 9、当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。 10、在Java中有两个常用的实现接口:Map 和 SortedMap,以及三个常用的实现类:HashMap,TreeMap 和 LinkedHashMap。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA2NDcwMzU_size_16_color_FFFFFF_t_70] ## 2、Map 类图 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA2NDcwMzU_size_16_color_FFFFFF_t_70 1] **已知Map子接口:** 1. Bindings 2. ConcurrentMap<K,V> 3. ConcurrentNavigableMap<K,V> 4. LogicalMessageContext 5. MessageContext 6. NavigableMap<K,V> 7. SOAPMessageContext 8. SortedMap<K,V> **已知Map实现类:** 1. AbstractMap 2. Attributes 3. AuthProvider 4. ConcurrentHashMap 5. ConcurrentSkipListMap 6. EnumMap 7. HashMap 8. Hashtable 9. IdentityHashMap 10. LinkedHashMap 11. PrinterStateReasons 12. Properties 13. Provider 14. RenderingHints 15. SimpleBindings 16. TabularDataSupport 17. TreeMap 18. UIDefaults 19. WeakHashMap ## 3、Map 方法说明 ## **int size()** 返回此映射中键 - 值映射的数量。 如果映射数量大于 Integer.MAX\_VALUE,则返回 Integer.MAX\_VALUE。 **boolean isEmpty()** 如果此映射不包含键 - 值映射,则返回 true。 **boolean containsKey(Object key)** 如果此映射包含指定键的映射,则返回 true。 **boolean containsValue(Object value)** 如果此映射将一个或多个键映射到指定值,则返回 true。 **V get(Object key)** 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 **V put(K key, V value)** 将指定的值与此映射中的指定键相关联。 如果映射到先前包含键的映射,则旧值将替换为指定的值。 (当且仅当m.containsKey(k)返回true时。) **V remove(Object key)** 如果存在键,则从该映射中移除键的映射。换句话说,如果此映射包含键 k 到值 v 的映射,使得(key == null?k == null:key.equals(k)),则删除该映射。 **void putAll(Map<? extends K,? extends V> m)** 将指定Map集合中的所有映射复制到当前Map集合,此调用的效果等同于在当前Map上调用put(k,v)的效果。 如果在操作过程中修改了指定的Map,则此操作的行为是不确定的。 **void clear()** 从此Map映射中删除所有映射。 **Set keySet()** 返回此映射中包含的键的Set视图。 因此对Map的更改将反映在集合中,反之亦然。 如果在对集合进行迭代时,修改了映射(除了通过迭代器自己的remove操作),迭代的结果是未知的。 该集合支持元素删除,它通过 Iterator.remove,Set.remove,removeAll,retainAll和clear操作从Map中删除相应的映射, 它不支持add或addAll操作。 **Collection values()** 返回此映射中包含的值的Collection视图。 如果在对集合进行迭代时修改了映射(除了通过迭代器自己的remove操作),迭代的结果是未知的。 该集合支持元素删除,它通过Iterator.remove,Collection.remove,removeAll,retainAll和clear操作从Map中删除相应的映射。 它不支持add或addAll操作。 **Set<Map.Entry<K,V>> entrySet()** 返回此映射中包含的映射的Set视图。 如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未可知的。 该集支持元素删除,它通过 Iterator.remove,Set.remove,removeAll,retainAll和clear操作从Map中删除相应的映射。 它不支持add或addAll操作。 **boolean equals(Object o)** 将指定对象与此映射进行相等性比较。 如果给定对象也是一个映射,并且两个映射表示相同的映射,则返回true。 也就是说,如果 m1.entrySet().equals(m2.entrySet()),则两个映射m1和m2表示相同的映射。 **int hashCode()** 返回此映射的哈希码值。 映射的哈希码被定义为映射的 entrySet()视图中每个条目的哈希码的总和。 这确保 m1.equals(m2)也就意味着 m1.hashCode()== m2.hashCode()。 > JDK 1.8 新增的默认实现方法如下 **default V getOrDefault(Object key,V defaultValue)** 返回指定键映射到的值,如果此映射不包含键的映射,则返回defaultValue。 **default void forEach(BiConsumer<? super K,? super V> action)** 对此映射中的每个条目执行给定操作,直到处理完所有条目或操作引发异常。 除非实现类另有指定,否则将按迭代的顺序执行操作,操作抛出的异常将返回给调用者。 for (Map.Entry<K, V> entry : map.entrySet()) action.accept(entry.getKey(), entry.getValue()); **default void replaceAll(BiFunction<? super K,? super V,? extends V> function)** 将每个条目的值替换为在该条目上调用给定函数的结果,直到所有条目都已处理或函数抛出异常。 函数抛出的异常将转发给调用者。 for (Map.Entry<K, V> entry : map.entrySet()) entry.setValue(function.apply(entry.getKey(), entry.getValue())); **default V putIfAbsent(K key,V value)** 如果指定的键尚未与值关联(或映射为null),则将其与给定值关联并返回null,否则返回当前值。 V v = map.get(key); if (v == null) v = map.put(key, value); return v; **default boolean remove(Object key, Object value)** 仅当指定键映射到指定值时才删除该条目。 if (map.containsKey(key) && Objects.equals(map.get(key), value)) { map.remove(key); return true; } else return false; **default boolean replace(K key, V oldValue,V newValue)** 仅当前映射到指定值时,才替换指定键的条目。 if (map.containsKey(key) && Objects.equals(map.get(key), value)) { map.put(key, newValue); return true; } else return false; **default V replace(K key,V value)** 仅当指定键映射到某个值时才替换该条目的条目。 if (map.containsKey(key)) { return map.put(key, value); } else return null; **default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)** 如果指定的键尚未与值关联(或映射为null),则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为null。 如果函数返回null,则不记录映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并且不记录映射。 最常见的用法是构造一个新对象,用作初始映射值或记录结果,如下所示: map.computeIfAbsent(key, k -> new Value(f(k))); 或者实现一个多值映射,Map <K,Collection >,支持每个键的多个值: map.computeIfAbsent(key, k -> new HashSet<V>()).add(v); 默认实现等效于此映射的以下步骤,然后返回当前值,如果不存在则返回null: if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) map.put(key, newValue); } **default V computeIfPresent(K key,BiFunction<? super K,? super V,? extends V> remappingFunction)** 如果指定键的值存在且为非null,则尝试在给定键及其当前映射值的情况下计算新映射。如果函数返回null,则删除映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并保持当前映射不变。 默认实现等效于对此映射执行以下步骤,然后返回当前值,如果不存在则返回null: if (map.get(key) != null) { V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) map.put(key, newValue); else map.remove(key); } **default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)** 尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为null)。 例如,要创建或追加 字符串 msg 到值映射: map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg)) 如果函数返回null,则删除映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并保持当前映射不变。 默认实现等效于为此映射执行以下步骤,然后返回当前值,如果不存在则返回null: V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (oldValue != null ) { if (newValue != null) map.put(key, newValue); else map.remove(key); } else { if (newValue != null) map.put(key, newValue); else return null; } **default V merge(K key,V value,BiFunction<? super V,? super V,? extends V> remappingFunction)** 如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。 否则,将相关值替换为给定重映射函数的结果,或者如果结果为null则删除。 当组合密钥的多个映射值时,该方法可以是有用的。 例如,要创建或附加String msg 到值映射: map.merge(key, msg, String::concat) 如果函数返回null,则删除映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并保持当前映射不变。 默认实现等效于为此映射执行以下步骤,然后返回当前值,如果不存在则返回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; } > 参考资料:[https://docs.oracle.com/javase/8/docs/api/java/util/Map.html][https_docs.oracle.com_javase_8_docs_api_java_util_Map.html] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA2NDcwMzU_size_16_color_FFFFFF_t_70]: /images/20220222/bebb9038c2bf479fab0d3456212e5b36.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA2NDcwMzU_size_16_color_FFFFFF_t_70 1]: /images/20220222/d36fadd02bc04a28b4aa12963bf2d841.png [https_docs.oracle.com_javase_8_docs_api_java_util_Map.html]: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
相关 Java集合框架(十五):TreeSet 源码分析 文章目录 1、TreeSet 简述 2、TreeSet源码分析 3、TreeSet排序方式 3.1、一是自然排 - 日理万妓/ 2022年05月28日 12:37/ 0 赞/ 193 阅读
相关 Java集合框架(十三):HashSet 源码分析 文章目录 1、简述 2、HashSet实现 3、常用方法 4、HashSet元素不重复原理 1、简述 Has 悠悠/ 2022年05月28日 12:25/ 0 赞/ 186 阅读
相关 Java集合框架(十八):HashMap 源码分析 文章目录 1.HashMap简述 2.HashMap数据结构 2.1.JDK1.7中HashMap数据结构 素颜马尾好姑娘i/ 2022年05月26日 00:54/ 0 赞/ 182 阅读
相关 Java集合框架(十七):LinkedList 源码分析 文章目录 1、LinkedList 简述 2、LinkedList 类图 2.1、LinkedList 内部结构 3 墨蓝/ 2022年04月24日 03:58/ 0 赞/ 246 阅读
相关 Java集合框架(十六):ArrayList 源码分析 文章目录 1、ArrayList 简述 2、ArrayList 类图 3、ArrayList 构造函数 3.1 向右看齐/ 2022年04月24日 03:04/ 0 赞/ 220 阅读
相关 Java集合框架(十一):Map 源码分析 文章目录 1、Map 简述 2、Map 类图 3、Map 方法说明 1、Map 简述 java.util.Map 接口表示 水深无声/ 2022年04月23日 23:26/ 0 赞/ 259 阅读
相关 Java集合框架(十):Deque 源码分析 文章目录 1、Deque 简述 2、Deque 类图 3、Deque 方法概述 1、Deque 简述 线性集合,支持两端插 心已赠人/ 2022年02月23日 10:18/ 0 赞/ 256 阅读
相关 Java集合框架(十二):SortedMap 源码分析 文章目录 1、SortedMap 简述 2、SortedMap 类图 3、SortedMap 方法说明 4、Sort 拼搏现实的明天。/ 2022年02月20日 14:26/ 0 赞/ 461 阅读
相关 Java集合框架(二十一):HashTable 源码分析 文章目录 1、HashTable 简介 1.1、HashTable 定义 1.2、HashTable 属性 秒速五厘米/ 2021年10月19日 06:56/ 0 赞/ 285 阅读
相关 Java集合框架(十九):LinkedHashMap 源码分析 文章目录 1、LinkedHashMap 简介 2、LinkedHashMap 数据结构 2.1、Entry 的继承体系 梦里梦外;/ 2021年10月18日 12:26/ 0 赞/ 321 阅读
还没有评论,来说两句吧...