Set 集合
Set集合实现类有哪些,各有什么特点
- HashSet 集合:无序,不重复,无索引
- LinkedHashSet:有序,不重复,无索引
- TreeSet:排序,不重复,无索引
Set集合底层是用什么实现的
哈希表
哈希表底层是什么组成的
Java1.8前:数组 + 链表
Java 1.8后:数组 + 链表 + 红黑树
对象的哈希值是怎么计算出来的
使用对象的地址,使用某种规则进行计算
所以相同地址计算的哈希值一定是相同的
哈希表的详细流程
- 创建一个默认长度16,默认加载因为0.75的数组,数组名table
- 根据元素的哈希值跟数组的长度计算出应存入的位置
- 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素, 则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入链表。
- Java1.8 之后,当链表长度达到8,就会自动转换为红黑树
- 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍
Set集合去重的原理
根据元素的哈希值,跟数组的长度取余,放入到位置上。
当位置上已经有元素,则调用 equals 方法进行比较,比较结果不同时才进行插入
最佳实践:如何另Set集合认为两个对象相同
重写 hashCode() 方法,使用指定的值作为哈希值,而不是使用地址值来计算哈希值
重写 equals() 方法,比较时使用指定的参数进行比较,而不是使用地址值进行比较
这样,将两个对象的 hashCode() 返回一致并 equals() 返回 true,两个对象就会被认为相同了
LinkedHashSet 为什么有序
linkedHashSet 在 HashSet 的基础上,每个元素增加了对前一个元素和后一个元素的指针,使得顺序被记录下来。也就是基于哈希表,增加了双链表的结构。
TreeSet 的特点是什么
排序,无索引,不重复
底层是由红黑树实现的
TreeSet如何对对象进行去重
TreeSet插入对象时,会调用比较器进行比较。
对于未实现 CompareTo() 方法的自定义类,无法进行比较。
这时候就需要我们自定义比较规则。
TreeSet 如何自定义比较规则
- 用来比较的类,实现 Comparable 接口,重写compareTo() 方法
- 自定义一个 Comparable 接口的比较器,在初始化 TreeSet 时作为参数传入构造器
- 如果TreeSet集合存储的对象有实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序
最佳实践:在以下场景应该使用什么集合
- 元素重复,要有索引,查询快 —— ArrayList
- 元素重复,要有索引,首尾元素增删快 —— LinkedList
- 元素不重复,无索引,无序,增删查找都快 —— HashSet
- 元素不重复,无索引,有序,增删查找都快 —— LinkedHashSet
- 对对象进行排序 —— TreeSet
可变参数
什么是可变参数
可变参数用在形参中可以接收多个数据,可以不接收参数,可以接收1个或者多个参数,也可以接收一个数组
可变参数的格式:数据类型…参数名称
可变参数的原理是什么
可变参数在方法内部本质上就是一个数组
如何使用可变参数
一个形参列表中可变参数只能有一个
可变参数必须放在形参列表的最后面
Map集合
Map 集合体系图
HashMap,LinkedHashMap,TreeMap 有什么区别
HashMap 的键无序
LinkedHashMap 的键有序
TreeMap 的键排序
HashMap,LinkedHashMap,TreeMap的实现原理
和 HashSet,linkedHashSet,TreeSet 的原理一样,只是多了一个值
使用基本上和 Set一致