一、说说有哪些常见集合?
主要分为3种:
1、List(列表)
2、Map(映射)
3、Set(集)
Collection接口:
【List接口】存储元素 有序、重复
【Set接口】存储元素 不有序、不重复(与List相反)
【Map接口】键值对映射结构的集合
具体如图:
二、List
1、ArrayList 和 LinkedList 的区别
ArratList:数组;利于查找;下标查找,支持随机访问;
LinkedList:双向链表;利于增删;不支持随机访问;
2、ArrayList 的扩容机制
先检查是否满了,如果满了则创建1.5倍的新数组,然后拷贝原数组值至新数组。
三、Map
1、HashMap 的数据结构
JDK1.7 = 数组 + 链表
JDK1.8 = 数组 + 链表 + 红黑树
- 数组(桶数组):存储数据元素;
- 链表:解决冲突;
- 红黑树:提⾼查询的效率;
通过映射关系(散列数组)到桶数组对应的索引:
1、若发生冲突,拉出一条链表,插入冲突元素
2、若链表长度 > 8 & 数组大小 >= 64 ,转为红黑树
3、若红黑树 > 6 ,转为链表。
2、红黑树了解多少?为什么不用二叉树 / 平衡树?
红黑树本质上是一种二叉查找树,为保持平衡,在二叉树查找树的基础上增加了一些规则。
- 节点要么红,要么黑
- 根节点永远是黑节点,所有叶子节点都是黑色的(NULL)
- 每个红节点的两个子节点都是黑
- 从任⼀节点到其子树中每个叶子节点的路径,都包含相同数量的黑色节点
如图所示:
效率问题:
红黑树:O(logn)
二叉树:O(n)
平衡树:效率更低
3、HashMap 如何查找元素?
(1)使用扰动函数,获取新的哈希值;
(2)计算数组下标,获取节点;
(3)当前节点和key匹配,直接返回;
(4)否则,判断当前是否是树节点,先找树后找表。
4、HashMap 的构造方法
(1)除留取余法;
(2)直接定址法;
(3)数字分析法;
(4)平⽅取中法;
(5)折叠法。
5、解决哈希冲突的方法
(1)链地址法;
(2)开放定址法;
(3)再哈希法;
(4)建⽴公共溢出区。
6、HashMap 的扩容机制
扩容之后的长度是原来的⼆倍,新的容量也是2的次幂,所以,元素,要么在原位置,要么在原位置再移动2的次幂。
7、HashMap JDK1.8的优化
(1)优化时间复杂度O(n) -->> O(logn);
(2)由头插法改尾插法;
(3)扩容判断优化成简单的判断,先插入再判断是否扩容;
(4)移位、异或只做一次,提高效率。
四、Set
HashSet 底层就是基于 HashMap 实现的。
除了 clone( )、writeObject( ) 、readObject( ) 是 HashSet ⾃⼰不得不实现之外,
其他⽅法都是直接调⽤ HashMap 中的⽅法。
参考资料:三分恶 - 面渣逆袭