List和Set都继承了Collection接口
list是Java中的一个接口,它位于java.util包中,是有序的集合,元素可以重复,每个元素都有自己的索引
list集合的实现类有ArrayList,LinkedList,Vector
ArrayList底层数据结构是动态数组(具有动态扩容的能力,当元素数量超过当前数据容量时,ArrayList会自动增加其容量),特点是查询快(数组有索引标记元素位置,查询的时候直接返回索引标记的数据即可),增 删慢(数组增加或者删除需要复制和移动数组中的数据),线程不同步
LinkedList底层数据结构是双向链表(每个节点都包含对前一个节点后一个节点的引用),特点是增删快(只需要修改节点的前后引用即可),查询慢(链表没有对数据进行位置标记,每次获取固定位置的数据需要循环遍历链表)
Vector底层数据结构是数组,线程同步(同步开销较高),性能不如ArrayList
set是Java中的一个接口,它位于java.util包中,是无序的集合,元素不能重复
set的实现类有HashSet,TreeSet,LinkerHashSet
HashSet (实际上是HashMap)底层数据结构是哈希表(数组+链表+红黑树),根据hashCode和equals方法来确定元素唯一性(基于HashCode来计算元素的存储位置,当存入的元素HashCode相同时,会调用equals方法进行确认,如果为true,则代表已经存在相同的元素)。允许存在null,但只能有一个。不保证集合的迭代顺序。线程不同步
LinkedHashSet底层是数据结构(哈希表+双向链表)双向链表用来存储顺序,继承了HashSet,但是保证集合的迭代顺序。线程不同步
TreeSet实现了SortedSet接口,底层数据结构是红黑二叉树,实际上是TreeMap,可以确保元素处于排序状态。支持两种排序方式 自然排序和定制排序。线程不同步,不能有重复数据,不能有null数据,存储的数据类型必须是一致的。
当向treeSet添加自定义对象时,有两种排序方式:自然排序和定制排序
自然排序需要自定义对象实现Comparable接口,并重写comparaTo方法,在此方法中指明自定义的类的属性排序。
定制排序需要实现Comparator接口
都需要重写hashCode()与equals()方法
HashSet的扩容机制
底层数据结构哈希表(数组+链表+红黑树)
- 添加一个元素时,先得到hash值,再将hash值转化为索引,放在数组中该索引的位置
- 找到数组中索引位置,查看该索引是否有元素
- 若没有元素,则直接添加。若有元素,则调用equals方法计较。如果相同则不添加,若不同则添加在链表的尾部
- Jdk8中当链表中的元素个数打到8个,同时数组中的个数超过64时,就会进化成红黑树(进一步提高查询效率)。若链表中的元素达到8个,而数组中的数据未到64,则按照数组容量*2进行扩容,直到扩容到64再树化
- 第一次添加时,系统会扩容到,阈值为加载因子(0.75)*16 = 12
- 当整个数组中的元素个数打到12个 时,在添加第13个元素时,会触发数组扩容,此时阈值变为32*0.75=24,以此类推直到数组容量达到64时再树化。