Map
Map 接口是在整个 Java 类集中保存双值(键值对),将键映射到值的对象。映射不能包含重复的键,每个键最多只能映射一个值。(类似函数y=f(x),一个x只能找到一个y,x为key,y为value)
Map是所有Map实现类的顶级父接口,其定义的方法有:
方法 | 描述 |
---|---|
int size(); | 返回Map存储键值对数量 |
boolean isEmpty(); | 判断此映射否为空,有则返回true |
boolean containsKey(Object key); | 判断此映射是否有存在指定的键(key),有则返回true |
boolean containsValue(Object value); | 判断此映射是否有存在指定的值(value),有则返回true |
V get(Object key); | 根据指定的键(key)取出该映射的值(value) |
V put(K key, V value); | 将指定的键(key)与值(value)存储在映射中 |
V remove(Object key); | 根据键(key)删除键值对 |
void putAll(Map<? extends K, ? extends V> m); | 将指定映射的所有映射复制到此映射 |
void clear(); | 清空映射(删除所有键值对) |
Set keySet(); | 返回键(key)的Set集合的视图 |
Collection values(); | 返回值(value)的Collecgion集合的视图 |
Map为接口,不能直接创建对象,在实际编写代码才使用其实现类HashMap、LinkedHashMap、TreeMap。
HashMap
HashMap是基于哈希表的`Map接口的实现。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
哈希表表也称散列表,基本数据结构可理解为对象数组+链表(二叉树)的实现。
对象数组也称为“桶”,存储对象时,根据对象的 hash值 找到存储的“桶”,如果“桶”没有存储对象,则储存在“桶”的第一个位置;如果“桶”存储了数据,会比较数据(equals),不同则按链表继续存储在后面。在java中,当桶中链表长度(存储的对象)达到8时,会转换为红黑树数据结构;当存储的对象数量(大于8)减少到6时,会由红黑树转换为链表。
HashMap默认初始“桶"的数量为16,散列因子为0.75(散列因子和HasnMap的自动扩容有关,当比例0.75的“桶"存储数据时,HashMap会扩容2倍,然后将数据重新存储在扩容后的HashMap中。散列因子的选择会影响查找数据的性能以及内存,当散列因子过小,查找数据速度快,但是占用内存高;当散列因子过小,查找数据的速度会慢,占用内存较低,这就要选着一个合适的散列因子。为什么java的HashMap选着0.75呢,这个问题java面试好像也问过,可以可以百度一下,附一篇知乎的回答:。面试官:为什么 HashMap 的加载因子是0.75? - 知乎 (zhihu.com))
采用HashMap存储的对象需要重新equals和hashcode方法。
LinkedHashMap
LinkedHashMap是哈希表和链表实现,具有可预测的迭代顺序。(储存的顺序)
TreeMap
TreeMap 子类是允许 key 进行排序的操作子类,其本身在操作的时候将按照 key 进行排序,另外,key 中的内容可以 为任意的对象,但是要求对象所在的类必须实现 Comparable 接口。
注:LinkedHashMap和TreeMap顺序的体现和LinkedSet、TreeSet相似,不做过多说明。常用方法即为实现Map接口的方法。