集合类中除了Collection接口之外,还有另外一个非常重要的接口:Map。在接下来的的几篇文章里,将对Map接口进行介绍。
Map接口不像Collection接口下面还有两个子接口,Map只有四个重要的实现类,分别是:
- HashMap
- Hashtable
- ConcurrentHashMap
- TreeMap
Map比起Collection最大的特点在于保存的元素。Collection每次只能保存一个元素,而Map每次可以进行一对对象的保存,我们将这一对对象第一个称为key,第二个称为value,它们合起来组成了一个键值对(key-value,每个key对应为一个value)。
因为两个对象的关系是一一对应的,所以可以很容易的通过一个key找到它对应的value。
Map的定义如下:
public interface Map<K, V>
Map中提供的方法有如下几种:
在以后的工程中,我们经常会使用如下几种:
// 添加元素,Collection中为add,而Map是put
public V value(K key, V value);
// 根据key获取其对应的value,如果没有对应关系,返回null
public V get(Object key);
// 获取Map对象中所有的key,以Set对象的形式进行返回
public Set<V> keySet();
// 获取Map对象中所有的value,以Collection对象的形式进行返回
public Collection<V> values();
// 将Map以Set的形式返回
public Set<Map.Entry<K, V>> entrySet();
细心的同学肯定能发现,在entrySet()方法里,返回的Set对象泛型为 Map.Entry
interface Entry<K, V> {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
/*
* 以下为与数据比较相关的方法
*/
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
}
我们可以很直观的感受到,接口Entry就是为了数据存在的一个接口。其实在Map接口的实现类中,Map的get/set方法也是调用了Entry接口中的方法。
打开Map接口的实现类HashMap的定义我们可以发现,HashMap的get()方法在底层调用了getNode()方法,而在getNode()中,底层的数据是一个Node类型的对象。
我们跳转至Node,果不其然,Node是Entry接口的在HashMap子类中的内部类。