java_集合体系之Map框架相关抽象类接口详解、源码——08
摘要:Set的实现是基于Map的、所以先搞懂Map、才能去理解Set、否则的话、直接去弄Set会觉得云里雾里、最后发现是浪费时间。这一节介绍关于Map的相关接口、抽象类的功能。
一:Map总体框架图
简单说明:
1、上图中虚线且无依赖字样、说明是直接实现的接口
2、虚线但是有依赖字样、说明此类依赖与接口、但不是直接实现接口
3、实线是继承关系、类继承类、接口继承接口
下面的介绍虽然这些都是关于抽象类、接口的定义、但是还是觉得从源码的方向介绍更能直观的说明问题、也更能加深对体系的理解、当然API同样不再给出、会在介绍其具体子类的时候将接口中的API和子类自己新增的API分离开来罗列。
二:Map<K, V>
1、接口简介:
a)以键值对的形式存储数据、每个键唯一对应一个值、键不允许重复、至于键是否允许为null、视子类而定。
b)其中存放元素是否有序、视子类而定、如HashMap无序、Hashtable有序、排序规则可选按自然排序或者指定排序方式。
c)允许以三种形式获取、迭代Map中的元素、获取键集、获取值集、获取键值实体。
d)子类必须提供两个构造方法、一个是空构造方法、一个是含有指定传入的Map结构中的所有键值对的构造方法(此构造方法是将指定传入的Map智中的键值对全部复制为自己的键值对)。
2、源码分析:
package com.chy.collection.core;
public interface Map<K,V> {
// Query Operations
/** 返回所有的映射的个数*/
int size();
/** 是否含有映射*/
boolean isEmpty();
/** 是否包含值为key的key*/
boolean containsKey(Object key);
/** 是否包含值为value的value*/
boolean containsValue(Object value);
/** 根据指定的key获取value*/
V get(Object key);
// Modification Operations
/** 将一个键值对放入到Map中、返回以前与key关联的值*/
V put(K key, V value);
/** 根据传入的key删除一个键值对、返回被删除的key映射的value*/
V remove(Object key);
// Bulk Operations
/** 将指定的Map中的所有的映射放入到当前Map中*/
void putAll(Map<? extends K, ? extends V> m);
/** 删除当前Map中所有映射*/
void clear();
// Views
/** 获取由Map中所有key组成的Set*/
Set<K> keySet();
/** 获取由Map中所有value组曾的Collection*/
Collection<V> values();
/** 获取由Map中所有映射组成的实体类Map.Entry<K, V>组成的Set*/
Set<Map.Entry<K, V>> entrySet();
/** 组成Map的键值对、仅在Iterator时使用*/
interface Entry<K,V> {
/** 获取当前映射的key*/
K getKey();
/** 获取当前映射的value*/
V getValue();
/** 设置当前映射的value*/
V setValue(V value);
/** 判断当前Entry是否与传入的Object相等*/
boolean equals(Object o);
/**获取当前Entry的哈希值*/
int hashCode();
}
// Comparison and hashing
/** 如果 m1.entrySet().equals(m2.entrySet()),则两个映射 m1 和 m2 表示相同的映射关系。*/
boolean equals(Object o);
/** 返回此映射的哈希值*/
int hashCode();
}
简单说明:Map的源码中的方法可以分成:查询、修改(包括添加、删除Map中的映射)、获取视图和一个仅在Iterator的时候使用的内部接口、接口中定义了操作迭代出的每个映射的方法——获取key、获取value、修改映射的value。源码==================
三:AbstractMap<K, V>
1、抽象类简介:
a)AbstractMap实现了Map接口、提供一些方法的实现、要求所有需要实现Map接口的实现类应该从AbstractMap中继承、可以大大简化编程的代码量。
b)AbstractMap中的方法的简单实现都是围绕第一个获取视图的方法Set<Map.Entry<K, V>> entrySet();得到entrySet、进而获取entrySet的Iterator来操作的、
c)获取视图的剩下两个方法方法是通过两个匿名类new AbstractSet<K>()、newAbstractCollection<V>来实现的。
d)还有两个内部类是维护键值对的。
2、源码分析:
package com.chy.collection.core;
import java.util.Iterator;
import java.util.Map.Entry;
public abstract class AbstractMap<K,V> implements Map<K,V> {
/** 默认的构造方法、供子类调用*/
protected AbstractMap() {}
// Query Operations
/** 返回当前Map映射个数*/
public int size() {
return entrySet().size();
}
/** 当前映射是否为空*/
public boolean isEmpty() {
return size() == 0;
}
/** 判断当前Map中是否有值为value的映射*/
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;
}
/** 判断当前Map中是否有键为key的映射*/
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的值*/
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;
}
// Modification Operations
/** 将一个映射放入到Map中、要求子类要有自己的实现*/
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) {
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;
}
// Bulk Operations
/** 将指定Map中所有键值对都放入到当前Map中*/
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();
}
// Views
transient volatile Set<K> keySet = null;
transient volatile Collection<V> values = null;
/** 获取有当前Map中所有key组成的Set*/
public Set<K> keySet() {
if (keySet == null) {
//通过匿名类的方式获取keySet实体类
keySet = new AbstractSet<K>() {
//实现获取Iterator的方法、并实现Iterator内部方法
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 contains(Object k) {
return AbstractMap.this.containsKey(k);
}
};
}
return keySet;
}
/** 获取当前Map所有value组成的集合*/
public Collection<V> values() {
if (values == null) {
//通过匿名类的方式获取Collection实体类
values = new AbstractCollection<V>() {
//实现获取Iterator的方法、并实现Iterator内部方法
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 contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
}
return values;
}
/** 获取由当前Map中所有映射组成的Set*/
public abstract Set<Entry<K,V>> entrySet();
// Comparison and hashing
public boolean equals(Object o) {
//如果是他本身、返回true
if (o == this)
return true;
//如果传入的不是Map、返回false
if (!(o instanceof Map))
return false;
Map<K,V> m = (Map<K,V>) o;
//优化操作、如果传入的Map的size与当前被比较的Map的size不同、那么就可确定这两个Map不相等
if (m.size() != size())
return false;
//比较两个Map中的所有value是否相等、相等则返回true、不相等则返回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;
}
/** 返回此映射的哈希码值。*/
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
/** 返回此映射的字符串表示形式。*/
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(", ");
}
}
/** 返回当前Map的克隆的值*/
protected Object clone() throws CloneNotSupportedException {
AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
/** 比较两个对象是否相等*/
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、此类支持setValue*/
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;
}
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、此类不支持 setValue 方法。一般用在多线程环境中*/
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();
}
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;
}
}
}
四:SortedMap<K, V>
1、接口简介:
a)进一步提供关于键的总体排序的Map。该映射是根据其键的自然顺序进行排序的,或者根据通常在创建有序映射时提供的Comparator 进行排序
b)插入所有有序映射的键都要实现Comparable接口、所有这些键都是可以比较的。
c)内部方法都是围绕key的排序定义的、概括为: (1)获取大于、小于指定键的子Map、 (2)获取key所在指定范围的子集Map。获取第一个、最后一个键、 (3)获取三种视图的方法。(4)获取当前集合的排序比较器。
2、源码分析:
package com.chy.collection.core;
import java.util.Comparator;
public interface SortedMap<K,V> extends Map<K,V> {
/** 返回对此映射中的键进行排序的比较器;如果此映射使用键的自然顺序,则返回 null。*/
Comparator<? super K> comparator();
/** 返回此映射的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)。*/
SortedMap<K,V> subMap(K fromKey, K toKey);
/** 返回此映射的部分视图,其键值严格小于 toKey。*/
SortedMap<K,V> headMap(K toKey);
/** 返回此映射的部分视图,其键大于等于 fromKey。*/
SortedMap<K,V> tailMap(K fromKey);
/** 返回此映射中当前第一个(最低)键。*/
K firstKey();
/** 返回此映射中当前第一个(最低)键。*/
K lastKey();
/** 返回在此映射中所包含键的 Set 视图。*/
Set<K> keySet();
/** 返回在此映射中所包含值的 Collection 视图。*/
Collection<V> values();
/** 返回在此映射中包含的映射关系的 Set 视图。*/
Set<Map.Entry<K, V>> entrySet();
}
五:NavigableMap<K, V>
1、接口简介:
a)是对SortedMap接口的扩展、
b)方法 lowerEntry
、floorEntry
、ceilingEntry
和higherEntry
分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry
对象。
c)方法 lowerKey
、floorKey
、ceilingKey
和higherKey
只返回关联的键。
d)可以按照键的升序或降序访问和遍历 NavigableMap
e)subMap
、headMap
和tailMap
方法与名称相似的 SortedMap
方法的不同之处在于:可以接受用于描述是否包括(或不包括)下边界和上边界的附加参数
f)firstEntry
、pollFirstEntry
、lastEntry
和pollLastEntry
方法,它们返回和/或移除最小和最大的映射关系(如果存在),否则返回 null
。
2、源码分析:
package com.chy.collection.core;
import java.util.NavigableSet;
public interface NavigableMap<K,V> extends SortedMap<K,V> {
/** 返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。*/
Map.Entry<K,V> lowerEntry(K key);
/** 返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。*/
K lowerKey(K key);
/** 返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。*/
Map.Entry<K,V> floorEntry(K key);
/** 返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。*/
K floorKey(K key);
/** 返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null。*/
Map.Entry<K,V> ceilingEntry(K key);
/** 返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。*/
K ceilingKey(K key);
/** 返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null。*/
Map.Entry<K,V> higherEntry(K key);
/** 返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。*/
K higherKey(K key);
/** 返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。*/
Map.Entry<K,V> firstEntry();
/** 返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。*/
Map.Entry<K,V> lastEntry();
/** 移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。*/
Map.Entry<K,V> pollFirstEntry();
/** 移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。*/
Map.Entry<K,V> pollLastEntry();
/** 返回此映射中所包含映射关系的逆序视图。*/
NavigableMap<K,V> descendingMap();
/** 返回此映射中所包含键的 NavigableSet 视图。*/
NavigableSet<K> navigableKeySet();
/** 返回此映射中所包含键的逆序 NavigableSet 视图。*/
NavigableSet<K> descendingKeySet();
/** 返回此映射的部分视图,其键的范围从 fromKey 到 toKey。*/
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive);
/** 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。*/
NavigableMap<K,V> headMap(K toKey, boolean inclusive);
/** 返回此映射的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。*/
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
/** 返回此映射的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)。*/
SortedMap<K,V> subMap(K fromKey, K toKey);
/** 返回此映射的部分视图,其键值严格小于 toKey。*/
SortedMap<K,V> headMap(K toKey);
/** 返回此映射的部分视图,其键大于等于 fromKey。*/
SortedMap<K,V> tailMap(K fromKey);
}