Map、AbstractMap、SortedMap、NavigableMap介绍(JDK1.8)
简介
Map接口与常见实现类的UML图:
-
Map实现的类存储对象是
键值对
。 -
AbstractMap抽象类实现了Map接口部分方法,那么其他Map实现类可以通过继承AbstractMap来
减少代码编写。
-
实现了SortedMap接口的Map实现类
具有排序键值对的功能。
-
NavigableMap接口继承自SortedMap接口,其具有获取
大于|等于某对象的键值对、小于|等于某对象的键值对。
-
Dictionary抽象类存储键值对
,与Map类似,但现在该类已过时。 -
HashMap继承AbstractMap类,
能存储键值对,但不能保证插入次序。
-
HashTable实现Map、继承Dictionary,即也能
存储键值对,但不保证次序。它是一个线程安全的类。
-
LinkedHashMap实现Map接口,继承HashMap,能
存储键值对,也保证次序。
-
TreeMap继承AbstractMap类,也实现了NavigableMap接口,即内部是是
有序的键值对。
Map
-
Map是一个操作键值对映射的接口,
一个键只能有一个,一个键对应一个值。
-
Map接口提供
三种视图
,分别是:键集、值集、键值集。
-
Map有些实现类能保证取出
键值对与插入键值对次序一致
,如LinkedHashMap;有些实现类能通过排序键值对
, 如TreeMap。
常用API
Modifier and Type | Method |
---|---|
void |
clear() |
default V |
compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
default V |
computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) |
default V |
computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
boolean |
containsKey(Object key) |
boolean |
containsValue(Object value) |
Set<Map.Entry<K,V>> |
entrySet() |
boolean |
equals(Object o) |
default void |
forEach(BiConsumer<? super K,? super V> action) |
V |
get(Object key) |
default V |
getOrDefault(Object key, V defaultValue) |
int |
hashCode() |
boolean |
isEmpty() |
Set<K> |
keySet() |
default V |
merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) |
V |
put(K key, V value) |
void |
putAll(Map<? extends K,? extends V> m) |
default V |
putIfAbsent(K key, V value) |
V |
remove(Object key) |
default boolean |
remove(Object key, Object value) |
default V |
replace(K key, V value) |
default boolean |
replace(K key, V oldValue, V newValue) |
default void |
replaceAll(BiFunction<? super K,? super V,? extends V> function) |
int |
size() |
Collection<V> |
values() |
keySet()返回键集,values()返回值集,entrySet()返回键值集
Map.Entry
Entry是Map内部接口,其功能是对键值对进行操作。
API
Modifier and Type | Method and Description |
---|---|
static <K extends Comparable<? super K>,V>Comparator<Map.Entry<K,V>> |
comparingByKey() 返回一个比较器 ,按键自然顺序比较Map.Entry 。 |
static <K,V> Comparator<Map.Entry<K,V>> |
comparingByKey(Comparator<? super K> cmp) 返回一个比较器,比较Map.Entry 按键使用给定的Comparator 。 |
static <K,V extends Comparable<? super V>>Comparator<Map.Entry<K,V>> |
comparingByValue() 返回一个比较器,比较Map.Entry 的自然顺序值。 |
static <K,V> Comparator<Map.Entry<K,V>> |
comparingByValue(Comparator<? super V> cmp) 返回一个比较器 ,使用给定的Comparator 比较Map.Entry 的值。 |
boolean |
equals(Object o) 将指定的对象与此条目进行比较以获得相等性。 |
K |
getKey() 返回与此条目相对应的键。 |
V |
getValue() 返回与此条目相对应的值。 |
int |
hashCode() 返回此映射条目的哈希码值。 |
V |
setValue(V value) 用指定的值替换与该条目相对应的值(可选操作)。 |
AbstractMap
属性
transient Set<K> keySet;键集视图
transient Collection<V> values;值集视图
源码分析
//唯一一个构造方法
protected AbstractMap() {}
//返回键值集元素个数
public int size() {
return entrySet().size();
}
//判断该容器是否为空
public boolean isEmpty() {
return size() == 0;
}
//查询该容器是否存在值为value
public boolean containsValue(Object value) {
//获取键值集的迭代器
Iterator<Entry<K,V>> i = entrySet().iterator();
//指定值为null的情况
if (value==null) {
//通过迭代器遍历该容器
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getValue()==null)
return true;
}
} else {//指定值不为null情况
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (value.equals(e.getValue()))
return true;
}
}
return false;
}
//查询该容器是否存在键为key
public boolean containsKey(Object key) {
//获取键集视图的迭代器
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
//指定值为null的情况
if (key==null) {
//通过迭代器遍历该容器
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
//指定值不为null的情况
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}
//通过键获取值,若查找不到返回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;
}
//通过键移除指定的键值对
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;
}
}
//oldValue为旧值
V oldValue = null;
if (correctEntry !=null) {
oldValue = correctEntry.getValue();
//调用迭代器移除方法
i.remove();
}
return oldValue;
}
//添加其他容器数据
public void putAll(Map<? extends K, ? extends V> m) {
//遍历容器内数据并一一添加
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
//对容器内所有映射
public void clear() {
//先获取键值集再调用删除方法。
entrySet().clear();
}
//获取键集视图
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
//如果成员变量 keySet 为 null,创建个空的 AbstractSet,并完成Iterator<K>()、size()、isEmpty()、clear()、contains(Object k)方法。
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;
}
//获取值集视图
public Collection<V> values() {
Collection<V> vals = values;
//如果成员变量 vals 为 null,创建个空的 AbstractSet,并完成Iterator<K>()、size()、isEmpty()、clear()、contains(Object k)方法。
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;
}
//获取键值集方法未定义
public abstract Set<Entry<K,V>> entrySet();
//判断对象o是否等于当前容器
public boolean equals(Object o) {
//判断地址相等
if (o == this)
return true;
//判断是否为同一类型
if (!(o instanceof Map))
return false;
//强转为 Map
Map<?,?> m = (Map<?,?>) o;
//判断大小是否相等
if (m.size() != size())
return false;
try {
//下面就是使用容器的迭代器遍历元素,在判断对象o的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 的 hashCode()
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
//是所有 Entry 哈希值的和
h += i.next().hashCode();
return h;
}
//返回此 AbstractMap实例的浅拷贝:键和值本身不被克隆。
protected Object clone() throws CloneNotSupportedException {
AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
//判读o1,02是否相等
private static boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
AbstractMap.SimpleEntry类:
表示可变的键值对
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 int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
}
AbstractMap.SimpleImmutableEntry类:
表示一个不可变的键值对
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接口
API
Modifier and Type | Method and Description |
---|---|
Comparator<? super K> |
comparator() |
Set<Map.Entry<K,V>> |
entrySet() |
K |
firstKey() |
SortedMap<K,V> |
headMap(K toKey) |
Set<K> |
keySet() |
K |
lastKey() |
SortedMap<K,V> |
subMap(K fromKey, K toKey) |
SortedMap<K,V> |
tailMap(K fromKey) |
Collection<V> |
values() |
源码
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<K> keySet();
//值集视图
Collection<V> values();
//键值集视图
Set<Map.Entry<K, V>> entrySet();
}
NavigableMap 接口
简介
NavigableMap是SortedMap的子接口,具有SortedMap更多功能。
方法 lowerEntry、floorEntry、ceilingEntry 和 higherEntry 分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象,如果不存在这样的键,则返回 null。
类似地,方法 lowerKey、floorKey、ceilingKey 和 higherKey 只返回关联的键。
firstEntry、pollFirstEntry、lastEntry 和 pollLastEntry 方法,它们返回和/或移除最小和最大的映射关系(如果存在),否则返回 null。所有这些方法是为查找条目而不是遍历条目而设计的。
API
Modifier and Type | Method |
---|---|
Map.Entry<K,V> |
ceilingEntry(K key) |
K |
ceilingKey(K key) |
NavigableSet<K> |
descendingKeySet() |
NavigableMap<K,V> |
descendingMap() |
Map.Entry<K,V> |
firstEntry() |
Map.Entry<K,V> |
floorEntry(K key) |
K |
floorKey(K key) |
SortedMap<K,V> |
headMap(K toKey) |
NavigableMap<K,V> |
headMap(K toKey, boolean inclusive) |
Map.Entry<K,V> |
higherEntry(K key) |
K |
higherKey(K key) |
Map.Entry<K,V> |
lastEntry() |
Map.Entry<K,V> |
lowerEntry(K key) |
K |
lowerKey(K key) |
NavigableSet<K> |
navigableKeySet() |
Map.Entry<K,V> |
pollFirstEntry() |
Map.Entry<K,V> |
pollLastEntry() |
NavigableMap<K,V> |
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) |
SortedMap<K,V> |
subMap(K fromKey, K toKey) |
SortedMap<K,V> |
tailMap(K fromKey) |
NavigableMap<K,V> |
tailMap(K fromKey, boolean inclusive) |