介绍
双列集合中,每次添加元素添加一对(2个)数值
每对元素之间是一一对应的
最顶层为Map,有三个实现类,如下图
双列集合特点
双列集合一次需要存一对数据,分别为键和值
键不能重复,值可以重复
键和值是一一对应的,每一个键只能找到自己对应的值
键+值这个整体 我们称之为“键值对”,或者“键值对对象”,在Java中叫做“Entry对象”
Map/双列集合基本方法
put,不仅仅是添加,还可以覆盖————当 要添加的键值对 的键值上 存有元素时,返回这个元素,没有则返回null————或者说,添加元素时,如果键已存在,则覆盖之前的值,否则直接添加上去————如下图
remove,返回删除的键对应的值
Map的三种遍历
通过键找值
1、获取所有的键
利用Map对象的keySet方法,获得一个Set对象,里面存储着所有的键
2、用迭代器、增强for、Lambda等方法遍历Set对象,获取所有的键,然后利用Map对象的get方法,get(键)——return 键对应的值,获得值
3、对键和值进行操作
通过键值对
通过Map对象的entrySet方法获取所有的键值对对象,然后遍历方法返回的Set集合
entrySet返回的Set集合的元素类型是Map.Entry< , >类型
这种数据有两个方法分别为,getKey(),获取这个元素的键,getValue(),获取这个元素的值
Lambda遍历
Map对象有个 forEach方法,参数是BiConsumer接口的对象
BiConsumer接口是个函数接口
遍历方式如下
HashMap
是Map的实现类,直接用Map的类方法就可以
特点
特点都是由键决定的:(键值)无序、不重复、无索引(不能通过索引得到值,只能通过键得到值)
HashMap跟Hashset底层原理是一模一样的,都是哈希表结构
底层原理
1、首先创建一个默认长度为16,默认加载因子为0.75的名为table的一个数组,再利用put方法就可以添加数据了
2、put方法会创建一个Entry对象,里边存有要添加的键和值
3、利用键计算出哈希值,再计算出在数组中应存入的索引index,如果此位置没有元素,为NULL,则直接把元素放进去
但如果此索引上已经有元素了,就会调用equals方法去比较键的属性值(只比较键的属性值)
4、如果比较结果一样,则覆盖原有的Entry对象
如果不一样,在JDK8之后,新元素直接挂在老元素的下面(放在链表的表尾)
5、当链表长度>8,而且数组长度 >= 64时,链表会自动转成红黑树
源码
总结
HashMap底层是哈希表结构
依赖hashcode方法和equals方法保证键的唯一性
如果键存储的是自定义对象,则需要重写hashCode和equals方法
如果值存储的是自定义对象,则不需要重写hashcode和equals方法
LinkedHashMap
特点
是HashMap的子类
由键决定:有序、不重复、无索引。
这里的有序指的是保证存储和取出的元素顺序一致
底层原理
底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
1、首先创建一个默认长度为16,默认加载因子为0.75的名为table的一个数组,再利用put方法就可以添加数据了
2、put方法会创建一个Entry对象,里边存有要添加的键和值
3、利用键计算出哈希值,再计算出在数组中应存入的索引index,如果此位置没有元素,为NULL,则直接把元素放进去
但如果此索引上已经有元素了,就会调用equals方法去比较键的属性值(只比较键的属性值)
4、如果比较结果一样,则覆盖原有的Entry对象
如果不一样,在JDK8之后,新元素直接挂在老元素的下面(放在链表的表尾)
5、当链表长度>8,而且数组长度 >= 64时,链表会自动转成红黑树
TreeMap
特点
TreeMap跟TreeSet底层原理一样,都是红黑树结构的
由键决定特性:不重复、无索引、可排序(对键进行排序)
注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
自定义排序规则
默认排序/自然排序
Javabean类实现Comparable接口,进而指定比较规则
this表示当前节点,o表示红黑树上每个节点,即当你在增加节点时,需要对每个节点都去调用这个方法,从而在最后判断出当前节点该放在红黑树的哪个地方,再然后进行红黑规则
比较器排序
创建TreeSet集合时,自定义Comparator比较器对象,指定比较规则
两者同时存在
如果默认排序和比较器排序都存在,排序时按比较器排序进行排序
总结
idea源码表示
Ctrl B进入源码页
Ctrl F12看此类的大纲
以HashMap类为例
蓝色的图标表示类——Class
红色的图标表示方法——method ——和类同名的是构造方法———不同名的是成员方法
对于成员方法,以下图为例
从左到右依次是,方法图标,方法名,形参,返回值
向上的箭头表示——是重写的父类或接口的方法,箭头后边是父类/接口的名称
绿色锁指的是public 灰色圆圈指的是private
向右的箭头表示——是来自于这个地方/继承的这个父类的方法
灰色的方法表示——是继承的父类的方法
f是field,是常量或者成员变量
I是接口
C是类,类里边的类是内部类