Map的学习笔记
首先,我们已经完成了对List的学习,现在我们就开始学习Map
首先,我们先看看Map的架构
我们可以看到
- Map是顶级接口类,他不继承或者实现别的接口
- Map代表着键值对的形式,既Key-Value
- AbstractMap是一个抽象类,它实现了Map中的许多方法,所有想实现Map接口的都可以继承这个类
- SrotedMap是一个有序的Map,可以排序键值对,排序的方法是通过比较器
- NavigableMap相比于SortedMap,它存在一系列的导航方法,如获取大于/等于/小于某对象的键值对
- TreeMap实现了NavigableMap,很明显他是一个有序的Map
- HashMap并没有实现排序的接口,说明是Map,但不有序
- WeakHashMap,与HashMap不同的是,WeakHashMap是弱键
- HashTble是继承于Directionary,但是HashTable是线程安全的
我们先看看各个抽象类的情况
1、Map
public interface Map<K,V>
Map是一个以键值对(Key-Value)形式的数据结构,Key是唯一的,且一个Key只能对应一个Value
简单来说,在Map接口中,规定了Map到底是什么样的数据结构,第二规定了Map所提供的方法
abstract void clear()abstract boolean containsKey(Object key)abstract boolean containsValue(Object value)abstract Set<Entry<K, V>> entrySet()abstract boolean equals(Object object)abstract V get(Object key)abstract int hashCode()abstract boolean isEmpty()abstract Set<K> keySet()abstract V put(K key, V value)abstract void putAll(Map<? extends K, ? extends V> map)abstract V remove(Object key)abstract int size()abstract Collection<V> values()
上面为一下Map常用Api
Map提供接口分别用于返回 键集、值集或键-值映射关系集。
①entrySet()用于返回键-值集的Set集合
②keySet()用于返回键集的Set集合
③values()用户返回值集的Collection集合
因为Map中不能包含重复的键;每个键最多只能映射到一个值。
所以,键-值集、键集都是Set,值集时Collection。
2、Map.Entry
简单来说Map中的Entry类就是把Map中的每一个K-V看做一个实体
abstract boolean equals(Object object)abstract K getKey()abstract V getValue()abstract int hashCode()abstract V setValue(V object)
Map.Entry的常用Api的,可以取出一个实体的的Key和Value的值
以往在遍历Map时
System.out.println("通过Map.keySet遍历key和value:");for (String key : map.keySet()) {System.out.println("key= "+ key + " and value= " + map.get(key));}
因为Map没有继承Itorable接口,所以没法用迭代器遍历
所以必须要通过返回一个Key的集合,通过不断遍历这个集合的Key,通过Key再找到value
但是通过Entry的话,返回一个Entry集合
System.out.println("通过Map.entrySet使用iterator遍历key和value:");Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();while (it.hasNext()) {Map.Entry<String, String> entry = it.next();System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());}
只需要遍历这个Entry就可以得到全部的Map值了
3、AbstractMap
public abstract class AbstractMap<K,V> implements Map<K,V>
AbstractMap实现了Map接口中的大部分方法,只保留了1个抽象方法等待着子类去实现
public abstract Set<Entry<K,V>> entrySet();
我们首先来看一下get方法在AbstractMap中是如何实现的
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;}
首先第一行就显示了
Iterator<Entry<K,V>> i = entrySet().iterator();
首先得到一个entrySet,再调用它的迭代器,来遍历整个Map
while (i.hasNext()) {Entry<K,V> e = i.next();if (e.getKey()==null)return e.getValue();}
其余需要查找数据的方法,都是通过entrySet来实现的
Tips
为什么entrySet().iterator()的存在的?(也就是为什么entrySet()存在迭代器?)
首先我们回到Map接口
Set<Map.Entry<K, V>> entrySet();
返回值类型是一个Set类型
public interface Set<E> extends Collection<E>
打开Set接口,可以发现Set接口是继承Collection的
public interface Collection<E> extends Iterable<E>
Collection是继承于Iterable接口的
所以entrySet()的迭代器方法是存在的
4、SortedMap
public interface SortedMap<K,V> extends Map<K,V>
上面我们提到SortedMap的接口是有序的Map接口
另外,所有SortedMap 实现类都应该提供 4 个“标准”构造方法:
(01) void(无参数)构造方法,它创建一个空的有序映射,按照键的自然顺序进行排序。
(02) 带有一个 Comparator 类型参数的构造方法,它创建一个空的有序映射,根据指定的比较器进行排序。
(03) 带有一个 Map 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系与参数相同,按照键的自然顺序进行排序。
(04) 带有一个 SortedMap 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系和排序方法与输入的有序映射相同。无法保证强制实施此建议,因为接口不能包含构造方法。
5、NavigableMap
public interface NavigableMap<K,V> extends SortedMap<K,V>
NavigableMap是继承SortedMap的一个接口,它提供了一种导航的情况
如获取大于/等于/小于某对象的键值对
/*** Returns the least key strictly greater than the given key, or* {@code null} if there is no such key.** @param key the key* @return the least key greater than {@code key},* or {@code null} if there is no such key* @throws ClassCastException if the specified key cannot be compared* with the keys currently in the map* @throws NullPointerException if the specified key is null* and this map does not permit null keys*/K higherKey(K key);
其中一个heightKey()方法的JDK注释
翻译过来就是,寻找出最近一个比给定key大的key值,如果不存在的话返回null
NavigableMap的API
abstract Entry<K, V> ceilingEntry(K key)abstract Entry<K, V> firstEntry()abstract Entry<K, V> floorEntry(K key)abstract Entry<K, V> higherEntry(K key)abstract Entry<K, V> lastEntry()abstract Entry<K, V> lowerEntry(K key)abstract Entry<K, V> pollFirstEntry()abstract Entry<K, V> pollLastEntry()abstract K ceilingKey(K key)abstract K floorKey(K key)abstract K higherKey(K key)abstract K lowerKey(K key)abstract NavigableSet<K> descendingKeySet()abstract NavigableSet<K> navigableKeySet()abstract NavigableMap<K, V> descendingMap()abstract NavigableMap<K, V> headMap(K toKey, boolean inclusive)abstract SortedMap<K, V> headMap(K toKey)abstract SortedMap<K, V> subMap(K fromKey, K toKey)abstract NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)abstract SortedMap<K, V> tailMap(K fromKey)abstract NavigableMap<K, V> tailMap(K fromKey, boolean inclusive)
6、Dictionary
Dictionary也是一个键值对的接口
public abstract class Dictionary<K,V>
Dictionary是Jdk1.0中所使用的Key-Value,现在可用Map代替,在此不做介绍
