双列集合 Map
每次存取都是一对儿元素
一、Map集合概述
1.1 Map集合即双列集合,集合中的每一个元素都是以key=value的形式成对儿出现的,一个key=value就是一个键值对。Java中用Entry类的对象来表示键值对对象
1.2 特点:键不能重复,值可以重复,每个键只能找到自己的对应的值
1.3 注意:Map系列的集合特点都是由键决定的,值只是一个附属品,值是不做要求的
1.4 Map集合体系
- 1.4.1 HashMap(由键决定特点):无序、不重复、无索引
- 1.4.2 LinkedHashMap(由键决定特点):有序、不重复、无索引
- 1.4.3 TreeMap(由键决定特点):按照大小默认升序排序、不重复、无索引
二、常用方法
三、遍历方式
3.1 键找值
- 先获取Map集合全部的键,再通过遍历键找值
•
3.2 键值对
- 直接获取每一个Entry对象,把Entry存储到集合中去,再通过Entry对象获取键和值
•
3.3 Lambda
- 需要使用forEach方法,最好结合Lambda表达式使用
•
四、HashMap
4.1 特点
- 无序、不重复、无索引
4.2 HashSet底层就是HashMap
- 创建HashSet集合时,底层帮你创建了HashMap集合;往HashSet集合中添加元素时,底层调用了Map集合的put方法把元素作为了键来存储,所以HashSet集合就是把HashMap集合的值忽略不看。
4.3 底层数据结构---哈希表结构
- 是一种增删改查性能都比较好的数据结构
- JDK8之前:哈希表=数组+链表
- JDK8之后:哈希表 =数组+链表+红黑树
4.4 底层存储步骤
- 1、第一次往HashMap集合中存储键值对时,底层会创建一个长度为16的数组
- 2、把键和值封装成一个对象,叫做Entry对象
- 3、根据Entry对象的键计算hashCode值(和值无关)
- 4、用哈希值和数组长度做求余算法,得到一个索引位置
- 5、判断这个索引的位置是否为null,如果为null,就直接将这个Entry对象存入这个索引位置;如果不为null,则进行下一步
- 6、使用equals方法判断两个对象的键是否相同,如果不同(false)则以链表的形式往下挂(JDK8开始 尾插法);如果相同(true),则认为键重复,此时新的键值对会替换旧的键值对
4.5 底层存储注意事项
- 1、底层数组默认长度为16,如果数组中有超过12位置已经存储了元素,则会对数组进行扩容2倍,数组扩容的加载因子为0.75,即阈值:16*0.75=12.
- 2、数组的同一个索引位置有多个元素、并且在8个元素以内(包括8)则以链表的形式存储
• JDK8以前:链表采用头插法
• JDK8以后:链表采用尾插法
- 3、数组的同一个索引位置有多个元素,并且超过了8个即链表长度超过8并且数组长度>=64,则转换成红黑树的形式
4.6 键的不可重复
- 往Map集合存储自定义对象作为键时,为了保证键的唯一性,应重写hashCode方法和equals方法
五、LinkedHashMap
5.·1 特点:有序、不重复、无索引
5.2 底层原理
- 底层多一个双向链表来维护键的存储顺序,取元素时,先取头节点元素,然后再依次取下一个节点,一直到尾节点,所以是有序的。
六、TreeMap
6.1 特点:默认按照键的升序排序、键不重复、无索引
6.2 底层原理
- 底层由红黑树实现,所以可以对键进行排序
6.3 排序规则
- 1、写个实现类来实现接口Comparable接口,重写compareTo方法
- 2、创建TreeMap集合时,直接传递Comparator比较器对象
6.4 注意:只有TreeMap的键才能排序,HashMap的键不能排序
七、集合嵌套示例