Map容器家族(AbstractMap源码详解)
一、在Map集合体系中的位置及概述
AbstractMap抽象类提供Map接口的骨干实现,以最大限度地减少实现此接口所需的工作量。
二、成员变量
// 保存key
transient Set<K> keySet;
// 保存value
transient Collection<V> values;
三、方法详解
1.添加方法
/**
* 功能:向map中添加元素
* 注:这个方法并没有实现
*/
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
2.删除方法
/**
* 功能:删除所有键值对
* 实现:
* 1.调用Set集合的clear方法进行删除
*/
public void clear() {
entrySet().clear();
}
3.修改方法(Modification Operations)
/**
* 功能:根据键移除该键值对
* 实现:
* 1.获取保存Entry的Set迭代器,并创建临时保存要删除的Entry的变量correctEntry
* 2.如果待删除的key为null:
* 2.1 如果correctEntry中没有元素并且有下一个元素进行迭代,比较key值是否为null,如果为null将该Entry赋给correctEntry,迭代结束
* 3.如果待删除的key不为null,操作同步骤2
* 4.如果correctEntry为null,函数直接返回null
* 5.如果correctEntry不为Null,将待删除的Entry值返回,并调用Set的remove方法删除该Entry
*/
public V remove(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
Entry<K,V> correctEntry = null;
if (key==null) {
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
correctEntry = e;
}
} else {
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
correctEntry = e;
}
}
V oldValue = null;
if (correctEntry !=null) {
oldValue = correctEntry.getValue();
i.remove();
}
return oldValue;
}
4.查询方法(Query Operations)
/**
* 功能:返回map元素个数
* 实现:
* 1.entrySet方法返回的是Set集合,调用Set集合的size方法获取键值对的个数
*/
public int size() {
return entrySet().size();
}
/**
* 功能:该map集合是否为空
* 实现:
* 1.通过判断集合元素个数size是否为0即可判断是否为空
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* 功能:判断集合是否包含指定值
* 功能:
* 1.获取键值对的Set集合
* 2.如果指定元素为null,使用Set迭代器遍历集合比较
* 3.如果指定元素不为null,使用Set迭代器遍历集合比较
* 4.如果没有找到返回false
*/
public boolean containsValue(Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (value==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getValue()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (value.equals(e.getValue()))
return true;
}
}
return false;
}
/**
* 功能:判断集合是否包含指定键
* 实现:同上一个方法
*/
public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}
/**
* 功能:根据键获取值
* 实现:
* 1.获取键值对的Set集合
* 2.如果指定的key为null,遍历集合,如果找到为null的key,则返回key
* 3.如果指定的key不为空,遍历集合,如果找到key,则返回key
* 4.如果没找到,则返回null
*/
public V get(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return e.getValue();
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return e.getValue();
}
}
return null;
}
5.批量操作(Bulk Operations)
/**
* 功能:添加一个map集合的元素到该集合中
* 实现:
* 1.使用增强for遍历该map的集合,使用put方法逐个添加
*/
public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
6.视图
/**
* 功能:返回键的Set集合
* 实现:
* 1.将keySet的地址应用赋给ks
* 2.如果ks没有为null(没有初始化),创建AbstractSet的子类并对其中的方法进行实现,获取到entrySet()
* 的迭代器,就等同于获取到他的所有元素;
* 3.返回ks
*
* 注:
* 1.这个方法的主体功能在调用的第一次会对keySet进行初始化,以后再次调用将不会执行主方法体,
* 直接返回keySet。
* 2.获取到一个结合迭代器在一定程度上就等同于获取到集合所有元素
*/
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new AbstractSet<K>() {
public Iterator<K> iterator() {
return new Iterator<K>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public K next() {
return i.next().getKey();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object k) {
return AbstractMap.this.containsKey(k);
}
};
keySet = ks;
}
return ks;
}
/**
* 功能:获取所有的值,并以Collection集合的形式返回
* 实现:原理同keySet方法
*/
public Collection<V> values() {
Collection<V> vals = values;
if (vals == null) {
vals = new AbstractCollection<V>() {
public Iterator<V> iterator() {
return new Iterator<V>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
values = vals;
}
return vals;
}
7.核心方法
public abstract Set<Entry<K,V>> entrySet();
8.比较和哈希(Comparison and hashing)
/**
* 功能:比较是否相等
* 实现:
* 1.如果o是本集合,则返回true
* 2.如果o数据类型不是map,则返回false
* 3.使用泛型通配符,将o转换成m
* 4.获取本集合的Entry迭代器
* 5.进行迭代分两种情况比较
*/
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;
}
/**
* 功能:返回次map集合的哈希值
* 实现:
* 1.遍历迭代每一个Entry,并将每个Entry的哈希值相加求和并返回
*/
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
9.其他方法
/**
* 功能:将map集合以字符串表示
* 实现:一看就能懂
*/
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
/**
* 功能:浅度克隆该map集合
* 注:不克隆键和值的集合
*/
protected Object clone() throws CloneNotSupportedException {
AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
四、两个实现了Entry接口的静态方法
这两个方法分别为SimpleEntry静态类和SimpleImmutableEntry静态类。这两个类的代码有99%都是相同的。只有setValue是不同的,SimpleEntry支持setValue功能而SimpleImmutableEntry不支持setValue方法,这也是这两个类的主要区别,即SimpleEntry是线程不安全的Entry的实现而SimpleImmutableEntry是线程安全的Entry的实现.
/**
* Map接口的Entry实现类
*/
public static class SimpleEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
private static final long serialVersionUID = -8499721149061103585L;
// key值
private final K key;
// value值
private V value;
/**
* 功能:构造方法
*/
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
/**
* 功能:构造方法
*/
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
/**
* 功能:获取键
*/
public K getKey() {
return key;
}
/**
* 功能:获取值
*/
public V getValue() {
return value;
}
/**
* 功能:设置值并返回以前的值
*/
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
/**
* 功能:比较两个Entry是否相等
*/
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
/**
* 功能:返回此SimpleEntry的哈希值
* 注:^ 为异或运算符
*/
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
/**
* 功能:返回此SimpleEntry的字符串表示
*/
public String toString() {
return key + "=" + value;
}
}
public static class SimpleImmutableEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
private static final long serialVersionUID = 7138329143949025153L;
private final K key;
private final V value;
/**
* 功能:构造方法
*/
public SimpleImmutableEntry(K key, V value) {
this.key = key;
this.value = value;
}
/**
* 功能:构造方法
*/
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
/**
* 功能:获取键
*/
public K getKey() {
return key;
}
/**
* 功能:获取值
*/
public V getValue() {
return value;
}
/**
* 功能:设置值
* 注:此方法,为了保证线程安全,此类不实现
*/
public V setValue(V value) {
throw new UnsupportedOperationException();
}
/**
* 功能:比较两个Entry是否相等
*/
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
/**
* 功能:返回此SimpleEntry的哈希值
* 注:^ 为异或运算符
*/
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
/**
* 功能:返回此SimpleEntry的字符串表示
*/
public String toString() {
return key + "=" + value;
}
}
五、总结
AbstractMap抽象类提供Map接口的骨干实现,以最大限度地减少实现此接口所需的工作量。
此类中有两个Map接口中Entry接口的静态实现,SimpleEntry类和SimpleImmutableEntry。SimpleEntry是线程安全的,SimpleImmutableEntry是线程不安全的。