1、List:有序可重复
(1)ArrayList:数组实现
初始容量:10 负载因子:1 扩容:1.5倍
创建数组的时候 长度是0;第一次添加元素的时候 初始化数组的长度10
底层调用Arrays.copyof()
(2)LinkedList:线性链表(1.5之前采用单向链表,1.5之后采用双向链表)
链表结构中的每一个元素 就叫做node对象
由于它的底层是用双向链表实现的,所以它对元素的增加、删除效率要比ArrayList好;
它是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。
(3)Vector:线程同步数组
当扩容因子大于0时,新数组长度为原数组长度+扩容因子,否子新数组长度为原数组长度的2倍。
(4)Stack:栈
初始容量:10 调用vector的扩容机制扩容
2、set:无序不重复
set集合就是map集合的一部分(key部分)
(1)HashSet:数组(16)+链表(单向链表)+树(红黑树)
HashMap中k-v中的k部分
初始容量:16 负载因子:0.75 扩容:2倍
扩容实现:
首先计算扩容大小:存储容量*2===>16*2=32; 申请线性表表空间,长度为32; 重新计算原来的数据在新数组中的位置,并进行复制;
hashset如何去重的:
hash值不同的两个元素 一定不是同一个元素 先判断hash值,后比较equals方法(地址)
(2)TreeSet:红黑树
TreeMap中k-v中的k部分,有序不可重复
排序方式:自然排序
如果是数值:值的大小 默认升序的
如果是字符串:字典顺序进行排序的
初始容量:16 负载因子:0.75 扩容:2倍
扩容实现:
首先计算扩容大小:存储容量*2===>16*2=32; 申请线性表表空间,长度为32; 重新计算原来的数据在新数组中的位置,并进行复制;
hashset如何去重的:
hash值不同的两个元素 一定不是同一个元素
先判断hash值,后比较equals方法(地址)
3、Map:键值对
(1)HashMap:数组(16)+链表(单向链表)+树(红黑树)
初始容量:16 负载因子:0.75 扩容:2倍
扩容实现:同上的HashSet
HashMap如何去重的:同上的HashSet
链表和树的转换:
链表结构转换为树结构的最大阀值:8(1.8之后的)
树结构转换为链表结构的阀值:6
因为是一个单向链表(8)所以查询的时候性能低,在1.8之后做了一个优化,当链表的 深度超过8的时候就将链表转换为树结构。
HashMap计算hash对key的hashcode进行了二次hash,以获得更好的散列值,然后对table数组长度取摸。
(2)TreeMap
同上面的TreeSet
初始容量:11 负载因子:0.75 扩容:2倍
(3)HashTable
初始容量:11 负载因子:0.75 扩容:2倍+1
扩容实现:同上的HashSet
HashMap如何去重的:同上的HashSet
Hashtable计算hash是直接使用key的hashcode对table数组的长度直接进行取模
(4)ConCurrentHashMap
既可以做到线程安全 又可以保证性能
采用:分段线程锁+读写锁
网友评论