前言
集合是java开发中的重点内容,需要掌握的东西很多,面试中可问的东西很多,无论是深度还是广度。集合框架中Collection对应的实现类如下所示,这些都是要完全掌握,一个可以分为三大类List集合、Set‘集合以及Map集合’。
其中Collection代表单列集合,而Map代表双列集合,即一个key和可以对应的键值对。
1.Collection集合
Collection集合包括List和Set。他们都有不同的实现类,使用不同的数据结构,实现不同的性能属性。比如ArrayList在查找上会快点,而插入和删除就性能就比较差,LinkedList插入比较快,但是查找性能比较差。
1 、 List系列集合:有序集合:添加的元素是有序、可重复、有索引的
- ArrayList、LinkedList:有序、可重复、有索引
- 2、Set系列集合:添加的元素无序、不重复、无索引
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:按照大小默认升序排序、不重复、无索引
代码验证本文省略掉了。可以在java环境中试试看看。
1.1 Collection常用的方法
常用的方法便是add()、clear()、isEmpty()、size()、remove()、toArray()
Collection的遍历方式,如下图所示:
这里推荐使用迭代器的方式进行遍历,经过实验证明,迭代器遍历是速度最快的 。
2.List集合
2.1 特点、特有的方法
List系列的集合特点:有序、可重复、有索引
2.2 List集合的特有方法
List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。
这一系列的集合中,因为List是有索引的,可以直接用for进行循环,其他Collection的遍历方式也能使用。
2.3 ArrayList底层原理
ArrayList基于素组实现的。其中,索引根据索引查找速度会比较快;查询数据通过地址和索引定位,查询任意值数据耗时相同。
删除效率低:可能需要把后面的数据前移。
添加效率极低:可能需要把后面很多的数据后移,再添加元素;或者也可能需要进行数组的扩容。
ArrayList底层原理
1 . 利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组;
2 .添加第一个元素时,底层会创建一个新的长度为10的数组;
3.存满时,会扩容1.5倍;
4.如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
2.4 LinkedList底层原理
LinkedList是基于双向链表实现的。链表有什么特点呢,首先链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址。
链表的添加过程如下所示:
查询慢的特点:无论查询哪个数据都要从头开始。
链表的特点:链表增删相对快。只是修改指针。对首尾元素增删改查的速度极快。
索引Linked特意添加了头部与尾部的增删改的操作。
3.Set集合
Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致;不重复;无索引。
- HashSet:无序、不重复、无索引。
- LinkedHashset:有序、不重复、无索引。
- Treeset:排序、不重复、无索引。
3.1 HashSet底层实现原理
需要也别说明的是,在真正了解HashSet集合的底层原理前,需要先搞清楚一个前置知识:哈希值。
HashSet集合的实现原理
- 基于哈希表实现。
- 哈希表是一种中增删改查数据,性能都好比较的数据结构。
哈希表 - JDK8之前,哈希表=数组+链表
- JDK8之后,哈希表=数组+链表+红黑树
关于红黑树,可理解为一颗自动平衡的二叉树。
HashTable是一种增删改查性能都较好的数据结构。
3.2 HashSet去重原理
3.3 LinkedHashSet集合
特点:有序、不重复、无索引;实现依旧是基于数组+链表+红黑树实现。但是,它的每个元素都额外的多了一个双链表的机制记录他前后的位置。
缺点:占用内存比较大。
3.4 TreeSet集合
特点:不重复、无索引、可排序(默认升序,按照元素大小,由小到大排序)。
底层实现时基于红黑树的排序 。
注意:
对于数字类型:Integer、Double,默认按照本身的大小进行升序排序。
对于字符串类型:默认按照首字母升序排序
对于自定义类型如Student对象,TreeSet无法直接排序。
自定义排序规则
具体实现代码如下所示:
关于Collection相关的集合已经结束,在工作过程中,可以根据集合的特性实现不同的业务功能。
注意并发执行修改出现的问题。如在集合遍历里面添加删除或者添加的问题。
修改后:
用增强for没办法解决并发修改的问题。
4.Map集合
4.1 前置知识:
可变参数
- 就是一种特殊的形参,定义在方法、构造器的形参列表里面,格式:数据类型…参数名称
可变参数的特点和好处 - 特点:可以不传数据给他,可以传一个或者同时传多个数据给它,也可以传一个数组给它。
- 好处:常常用来灵活的接收数据
4.2 概述
- Map集合称为双列集合,格式:{key1=value1,key2=value2,key3=value3,….,一次需要存一对数据做为一个元素。
- Map集合的每个元素“key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做“键值对集合。
- Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值。
在开发中,如果遇到存储一一对应的数据时,就可以考虑使用Map集合来做。
Map集合体系的特点
注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
- HashMap(由键决定特点):无序、不重复、无索引;(用的最多)
- LinkedHashMap (由键决定特点):由键决定的特点:有序、不重复、无索引。
- TreeMap (由键决定特点):按照大小默认升序排序、不重复、无索引。
4.3 Map集合常用的方法以及遍历
常用的方法: put(key,value),get(key),clear,isEmpty()。无非就是增删改查,清空的操作,判断是否为空。本文不进行代码实操了,有专门的javaapi文档,所以不需要记住,就跟我们不认识的字要去查字典一样。
遍历:一共就有三种,具体如下图所示:
第一种 方法:
代码实现:
第二种遍历方式:
第三种遍历方式:
推荐使用,代码太简单。直接上代码吧。
4.4 HashMap集合
特点:无序、无重复、无索引。
底层原理
- HashMap跟Hashset的底层原理是一模一样的,都是基于哈希表实现的。
实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已
哈希表: - JDK8之前,哈希表=数组+链表
- JDK8之后,哈希表=数组+链表+红黑树
- 哈希表是一种增删改查性能都较好的数据结构。
- HashMap的键依赖hashCode方法和equals方法保证键的唯一。
- 如果键存储的是自定义类型的对象,可以通过重写hashcode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。
4.5 HashMap集合
LinkedHashMap集合的原理:
底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)。
实际上:原来学习的LinkedHashset集合的底层原理就是LinkedHashMap。
4.6 TreeMap特点
TreeMap (由键决定特点):按照键的大小默认升序排序、不重复、无索引。
TreeMap
特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键排序)
原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。
TreeMap集合同样也支持两种方式来指定排序规则
让类实现Comparable接口,重写比较规则。
TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。
或者这样更加灵活
结束语
结束了,关于集合看起来很多,其实有些实现原理是重复的,比如Set和Map的实现类,Set的实现类是基于Map实现的。