一、概述
之前分析了顶级接口,java.util.Map接口,此次分析Map抽象基类java.util.AbstractMap。
抽象类AbstractMap实现了Map接口,提供Map接口和实现类之间的抽象,实现通用方法。
二、源码分析
public abstract class AbstractMap<K,V> implements Map<K,V> { 唯一构造函数,用于子类构造函数调用,隐式,包内可见 protected AbstractMap() { } // 查询操作 /** * 返回key-value集合视图的大小 */ public int size() { return entrySet().size(); } /** * 如果键值对集合视图无元素,返回true */ public boolean isEmpty() { return size() == 0; } /** * 判断是否包含指定值 * 通过键值对集合的迭代器遍历 * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public boolean containsValue(Object value) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (value==null) { // 需要对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; } /** * 判断键值对集合视图是否包含指定key * 通过键值对集合的迭代器遍历 * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ 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; } /** * 从键值对集合中通过指定key获取对应的value * 通过键值对集合的迭代器遍历 * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ 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; } // 修改操作 /** * 不支持的方法,需要实现类实现 */ public V put(K key, V value) { throw new UnsupportedOperationException(); } /** * 删除指定key * 通过键值对集合的迭代器遍历 */ public V remove(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); Entry<K,V> correctEntry = null; if (key==null) { // 如果keyweinull,找出key为null的entry 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) { // 如果存在指定的entry,通过迭代器删除,返回旧值 oldValue = correctEntry.getValue(); i.remove(); } return oldValue; } // 批处理操作 /** * 批量新增,遍历指点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()); } /** * 清空键值对集合,等同于清空map */ public void clear() { entrySet().clear(); } // 视图 /** * Key视图和Value视图 * Lazy加载,当视图第一次被使用的时候才会被初始化 * 因为其是没有状态的,所以只需要一个实例 * ps:没有同步锁操作,可能会有锁竞争产生 * transient 关键字:不需要被序列化,字面意思,临时的 */ transient Set<K> keySet; transient Collection<V> values; /** * 返回Key集合视图,由于key互异唯一,所以返回Set集合 * 具体实现:返回AbstractSet子类对象,其结果通过entrySet()构造,与调用类有关 * * Set只会在第一次请求时初始化,之后多次请求返回相同的对象; * 没有同步,所以有小概率发生并发请求,返回不同的set对象的情况 */ public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { // Lazy 加载,需要时加载 ks = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { // 迭代器使用entrySet的迭代器 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() { AbstractMap 的方法 return AbstractMap.this.size(); } public boolean isEmpty() { AbstractMap 的方法 return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap 的方法 AbstractMap.this.clear(); } public boolean contains(Object k) { AbstractMap 的方法 return AbstractMap.this.containsKey(k); } }; keySet = ks; } return ks; } /** * 类似KeySet,value不唯一且不互异,返回Collection集合 * */ 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; } /** * 键值对集合视图,抽象方法,由具体的子类实现 * 键值对互异,所以返回Set结构 */ public abstract Set<Entry<K,V>> entrySet(); // 比较和散列 /** * 相等方法 */ public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map)) // 类型判断 return false; Map<?,?> m = (Map<?,?>) o; // 强转 // 1.大小不等,则不相等 if (m.size() != size()) return false; try { // 2.遍历当前map键值对,判断指定map是否包含所有的键值对 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的散列码, */ public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; } // 返回String的字符串表示 public String toString() { Iterator<Entry<K,V>> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; // StringBuilder非线程安全 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(' '); } } // 返回浅拷贝对象(包内、子类可见) protected Object clone() throws CloneNotSupportedException { AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone(); result.keySet = null; result.values = null; return result; } /** * Utility method for SimpleEntry and SimpleImmutableEntry. * Test for equality, checking for nulls. * * NB: Do not replace with Object.equals until JDK-8015417 is resolved. */ private static boolean eq(Object o1, Object o2) { return o1 == null ? o2 == null : o1.equals(o2); } // Implementation Note: SimpleEntry and SimpleImmutableEntry // are distinct unrelated classes, even though they share // some code. Since you can't add or subtract final-ness // of a field in a subclass, they can't share representations, // and the amount of duplicated code is too small to warrant // exposing a common abstract class. // 不可变键-可变值的键值对 维护对象,Entry接口的实现 public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = -8499721149061103585L; private final K key; private V value; // 构造函数 public SimpleEntry(K key, V value) { this.key = key; this.value = value; } // 通过指定entry来构建 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; } 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()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } } // 不可变键值对 Entry对象 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; } // 不支持Set方法 public V setValue(V value) { throw new UnsupportedOperationException(); } 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()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } } }