Java中的集合
Collectionl
List
特点:有序、可重复、支持索引
ArrayList
数组的主要特点是:
查询速度快:根据索引查询数据块,查询数据通过地址和索引定位,查询任意数据耗时相同。
删除效率低:可能需要把后面很多数据进行前移
添加效率低:可能需要把很多数据往后移动,再添加元素;或者也能需要进行数组扩容。
底层原理:
arryList底层是用数组实现,数组是内存中一块连续的内存;
1、利用无参构造从创建的集合,会在底层创建一个默认长度为0的数组。
2、添加第一个元素时,底层会创建一个新的长度为10的数组。
3、当添加元素超过10后会扩容1.5倍
4、如果原来的数组中有10个数据,现在往这个集合里添加11个数据,那么会创建一个数组长度为实际实际数组长度的数组,也就是这个案例中的新数组长度为21,
应用场景:
1、适合索引查询数据,比如根据随机索引区数据,获得数据量不大时。
2、不适合数据量大,又要频繁的进行增加删除操作。
LinkedList
基于双链表实现的,可实现队列、栈等功能
底层原理:
采用双向链表实现,链表中的节点是独立的对象,在内存中是不连续的,每个节点包含数值和下一个节点的地址
单向列表特点:
查询慢:无论查询哪个数据都要从头开始找。
增删快:只要改指向下个值的内存地址即可。
双向列表:
查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
Set
set集合特点:添加数据的顺序和获取数据的顺序不一致,不可重复,无索引
HashSet
特点:无序、不重复、无索引
底层原理:
JDK8之前HashSet集合的底层原理基于哈希表(数组+链表),JDK8以后HashSet的底层基于哈希表(数组+链表+红黑树):当链表长度超过8,且数组长度>=64时,自动转为红黑树
1、创建长度为16的数组,默认加载因子为0.75,数据名table
2、使用元素的哈希值和数组的长度求余,计算出应存入的位置。
3、判断当前位置是否为null,如果为null直接存入,
4、如果不为null,表示有元素,则调用equeals进行比较,相同则不存,不相同则存入数组。
4.1、JDK8以前,新元素存入数据,占用老元素位置,老元素挂在下面
4.2、JDK8以后,新元素挂在老元素下面
LinkedHashSet
特点:有序、不重复、无索引
底层原理:基于哈希表(数组、双链表、红黑树)
TreeSet
特点:排序、不重复、无索引(默认升序排序,按照元素的大小,又小到大排序)
底层原理:底层基于红黑树实现的排序
注意:对于数字类型,默认按照数值本身的大小进行升序排序,对字符串,默认按首字母的标号升序排序。
自定义排序规则:
方式1:自定义类型需要实现Comparable接口,重写里面的compareto方法来指定比较规则
方式2:通过TreeSet有参构造器,可以设置Comparator对象
如何选择集合存储数据:
1、如果希望记住元素的添加顺序,需要存储重复元素、又要频繁的根绝索引查询数据;那么选择ArraList(有序、可重复、有索引),底层基于数组。
2、如果希望技术元素的添加顺序,且增删收尾数据的情况较多,那么选择linkedList(有序、可重复、有索引),底层基于双向列表实现
3、如果不在意元素的顺序,也没有重复元素存储,只希望增删改查都快,那么选择HashSet(无需、不重复、无索引),底层基于哈希表实现
4、如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快,那么选择LinkedHashSet(有序、不可重复、无索引),底层基于哈希表和双向列表实现
5、如果要对元素进行排序,也没有重复元素需要存储,且希望增删改查都快,那么选择TreeSet集合,底层基于红黑树实现。
Map
HashMap
实现方式:
hashMap地城是基于哈希表实现的
特点:
无序、不重复、无索引
hashMap的键依赖hashCode于equals方法保证键唯一
如果存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。
LinkedHashMap
实现方式:哈希表+双向列表实现
底层实现方式:与LinkedHashSet一样
TreeMap
特点:不重复、排序、无索引(按照键的大小排序,只能对键排序)
原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现排序。
自定义排序规则:
方式1:自定义类型需要实现Comparable接口,重写里面的compareto方法来指定比较规则
方式2:通过TreeSet有参构造器,可以设置Comparator对象