特点:
1.map集合的结构是: 键值对、KEY与VALUE、Map.Entry<K,V>的映射关系
2.map中key值不允许重复,如果重复,对应的value会被覆盖
3.map中的映射关系是无序的,无下标
4.map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代
5.Map的底层是数组加链表,初始容量是16,默认的加载因子是0.75,翻倍扩容,存储过程是将key的哈希值以数组长度取余,以余数值为数组下标放到数组,如果余数与之前元素相同,就以链表的形式追加在其后面,当链表长度>8时链表会转换成红黑树,当红黑树长度<6时红黑树才会恢复成链表
存储过程:
Map的底层为数组加链表,是一个Entry[ ]数组,初始容量是16,默认的加载因子是0.75;
存放数据时,会在拿到key值后,先求出key的哈希值,以数组长度取余,以余数值为数组下标放到数组中,当长度达到数组长度的0.75(加载因子)时,翻倍扩容;
(例如初始长度16时,存值到12个时,达到四分之三,在存第13个元素时,容量翻倍为32)
如果余数与之前元素相同(哈希碰撞/哈希冲突),就以链表的形式追加在其后面(所以数组中的元素都是最早加入的元素)
当链表长度>8时链表会转换成红黑树,当红黑树长度<6时红黑树才会恢复成链表
正是因为数组会扩容导致长度变化,而元素key的hash值不会变,所以每次扩容后每个元素Entry都要重新计算搬家
方法及测试:
常用方法:
int hashCode()返回本集合的哈希码值
boolean isEmpty()判断集合是否为空
int size() 返回本集合中键值对的个数
clear()清空
boolean containsKey(Obiect key) 判map中是否包含指定的key
boolean containsValue(Obiect value) 判断map中是否包含指定的value
V get(Object key) 根据指定的key返回对应的value,如果不存在,返回null
V remove(Object key) 删除本集合中参数key对应的键值对
V put(K key,V value) 向集合中添加键值对(映射关系 )
void putAll(Map<> m)向本集合中添加参数m集合的所有键值对 (映射关系)
Collection<V> values()把本map中的Value值取出放入一个Collection中并返回这Collection
第一种Set<K> keySet()把本map中的Key值取出放入一个Set集合中并返回这个Set集合
第二种Set<Map.Entry<K,V>> entrySet()把本map中的每一对KV都看成是一个Entry,把所有的Entry取出放入一个Set集合中并返回这个Set集合
Map集合的迭代方式详解:
Map本身没有迭代器,但有两种方法可以转化为Set集合再迭代
第一种:
调keySet()方法把所有key取出来放入一个set集合,再通过key来getValue
第二种
第二种是调entrySet()方法,把所有Enter取出放set,这里可以把map中每一个k-v键值对看作是一个Enter<k,v>,返回的Set泛型是 <Map.Entry<Key的泛型,Value的泛型> >,写成泛型套泛型的形式,这里因为Enter接口是Map接口下的一个子接口(类似于内部类),而别的类也会有Enter,所以Enter在写的时候要指明是map下的Enter,否则报错;
然后获取Set的迭代器时,因为这个Set泛型是Entry,所以迭代器的泛型也是<Map.Entry<Integer,String>>
.....