java容器类2:Map及HashMap深入解读

Java的编程过程中经常会和Map打交道,现在我们来一起了解一下Map的底层实现,其中的思想结构对我们平时接口设计和编程也有一定借鉴作用。(以下接口分析都是以jdk1.8源码为参考依据)

1. Map An object that maps keys to values. A map cannot contain duplicate keys;
each key can map to at most one value.

Map提供三种访问数据的方式: 键值集、数据集、数据-映射,对应下表中的标记为黄色的三个接口。public interface Map<K, V>

方法名   描述  
void clear()   从此映射中移除所有映射关系(可选操作)。  
boolean containsKey(Object key)   如果此映射包含指定键的映射关系,则返回 true。  
boolean containsValue(Object value)   如果此映射将一个或多个键映射到指定值,则返回 true。  
Set<Map.Entry<K,V>> entrySet()   返回此映射中包含的映射关系的 Set 视图。  
boolean equals(Object o)   比较指定的对象与此映射是否相等。  
V get(Object key)   返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。  
int hashCode()   返回此映射的哈希码值。  
boolean isEmpty()   如果此映射未包含键-值映射关系,则返回 true。  
Set<K> keySet()   返回此映射中包含的键的 Set 视图。  
V put(K key, V value)   将指定的值与此映射中的指定键关联(可选操作)。  
void putAll(Map<? extends K,? extends V> m)   从指定映射中将所有映射关系复制到此映射中(可选操作)。  
V remove(Object key)   如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。  
int size()   返回此映射中的键-值映射关系数。  
Collection<V> values()   返回此映射中包含的值的 Collection 视图。  

在Java8中的Map有增添了一些新的接口不在上述表格之中,这里不一一列举。

这里涉及到一个静态内部接口:Map.Entry<K,V> ,用于存储一个键值对,该接口中设置set和get键值和value值的接口。

image

所以Map中存储数据都是以这种Entry为数据单元存储的。

2. AbatractMap

AbstractMap中增加了两个非常重要的成员变量:

transient Set<K> keySet;
transient Collection<V> values;

通过这两个成员变量,我们已经知道Map是如何存储数据的了:键值存入keySet中,value存入values中。(由于Map需要保证键值的唯一性所以选择Set作为键值的存储结构,而Value则对此没有任何要求所以选择Collection作为存储结构)

AbstractMap实现了Map中的部分接口,都是通过调用接口:Set<Entry<K,V>> entrySet() 实现的,而该接口的具体实现却留给了具体的子类。以下代码列出了equal()方法的具体实现:

public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map)) return false; Map<?,?> m = (Map<?,?>) o; if (m.size() != size()) return false; try { Iterator<Entry<K,V>> i = entrySet(). iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) return false; } else { if (!value.equals(m.get(key))) return false; } } } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } return true; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzjjy.html