Map源码其实没什么好分析的,因为只是一个最顶层集合的接口;但是为了后续能够分析各个Map实现类的源码(如下图),还是先了解一下Map的方法接口和一些细节。(JDK版本1.8)
int size();//获取集合元素个数
boolean isEmpty();//判断几个是否为空
boolean containsKey(Object key);//判断集合里是否有这个key,如果传入的key类型不是集合对象指定的键类型或其子类型,将抛出类型转换异常可以传入null值,但如果集合不存在null键时,将抛出空指针异常
boolean containsValue(Object value);//同containsKey(),判断是否存在这个value
V get(Object key);//同containsKey(),并将存在key对应的value返回
V put(K key, V value);//将key-value对放入集合,如果key已经存在,则更新原来的value,允许key为null,但可能发生不支持此操作、类型转换、空指针等异常。
V remove(Object key);//删除元素并将删除的元素返回,同理可能发生put()方法的异常
void putAll(Map<? extends K, ? extends V> m);//将一个map集合的元素放入此map集合,可能发生同put()方法的异常,同时m中如果有不能放在此集合的元素,将抛出非法参数异常
void clear();//清空集合
Set<K> keySet();//获得集合所有key组成的set集合,set不允许存在重复元素,可以通过此方法先获取map集合的所有key,再遍历map里面的所有的value
Collection<V> values();//获得集合所有value组成的collection集合,
Set<Map.Entry<K, V>> entrySet();//获得一个Map.Entry数组组成的set集合,
//Map.Entry接口,用于映射key-value键值对,在Map后续的子类中,都实现此内部接口来完成不同特性的Map
interface Entry<K,V> {
//省略内部接口方法声明,有兴趣的可以去看Map的源码,此接口相当于一个简单的JavaBean,具备k-v的set和get方法声明,还有一些静态方法
}
boolean equals(Object o);//比较两个集合是否相等,实现equals方法务必同时实现hashCode方法,以免产生不必要的bug(比如相同的对象返回false、不同的对象返回true)。
int hashCode();//获取hash值,一般用于获取key的hash值
default V getOrDefault(Object key, V defaultValue) {
//获取默认的value值,当传入的v为空并且key对应的value为空时将默认的value值传给真正的value
}
default void forEach(BiConsumer<? super K, ? super V> action) {
//对map发生forEach操作时,将遍历每个key和value值,并执行指定的操作,直到遍历所有元素或者发生异常为止
}
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
//取代每个条目的值与给定的函数调用,进入结果直到所有条目都处理或函数抛出异常。
}
default V putIfAbsent(K key, V value) {
//如果key已经对应了一个value,则直接返回,否则将key-value键值对放入map
}
default boolean remove(Object key, Object value) {
//移除元素,先根据key获取curValue,如果curValue和value不相等或者value为空并且key不在map集合中,则说明要移除的元素不存在,直接返回false,否则移除元素并返回true
}
default boolean replace(K key, V oldValue, V newValue) {
//更新元素,先根据key获取curValue,如果curValue和oldValue不相等或者curValue为空并且key不在map集合中,则说明要更新的元素不存在,直接返回false,否则将newValue放入并返回true
}
default V replace(K key, V value) {
//更新元素,先根据key获取curValue,如果curValue不为空,或key在map元素中,则将value放入map集合并返回
}
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
//根据key获取map中的value,如果不为空,则返回,若为空,则根据key调用mappingFunction.apply()获取mValue,如果mValue不为空,则将此mValue放入map集合并返回mValue;
}
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
//根据key获取map中的oldValue,如果oldValue不为空,则根据key和oldValue调用remappingFunction.apply()方法获取newValue,如果newValue不为空,则将newValue放入map集合并返回,否则移除oldValue并返回null
}
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
//根据key获取oldValue,根据key和oldValue调用remappingFunction.apply()方法获取newValue,如果newValue不为空则直接将newValue放入key映射的value并返回value,否则移除oldValue并返回空。
}
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
//根据key获取oldValue,如果oldValue为空,则将value的值给newValue,否则根据key和oldValue调用remappingFunction.apply()方法获取newValue,如果newValue为空,则将key移除map集合并返回null,否则将newValue放入key映射的value,并返回value
}
Map虽然只是一个接口,但是看到map源码的分析,并不是单纯的只是一些方法的定义,还存在default的方法和static的方法,这是JDK1.8对接口进行的拓展,使得其实现类可以不用重复实现代码一样的操作方法了,算是具备了一部分虚类的功能;Map接口default实现的方法在其实现类中都是一些基本的需要用到的方法,后续将继续分析Map的几个实现类。
写在最后,初学Java时间不长,以前从未想过写博客,都是写markdown在本地PC端保存学习内容,后面会陆续将markdown的学习笔记换成博客的形式发布在网络,算是对学过的内容进行简单的复习,同时以便自己能不在PC旁时仍能翻看学习内容。本人菜鸟中的小白,如有错误,忘各位大佬批评指正。