Collection
List
- 有序的;
- 可重复的; | 类 | 底层结构 | 增删的效率 | 改查的效率 | | —- | —- | —- | —- | | Vactor | 可变数组 | 较低 | 较低 | | ArrayList | 可变数组 | 较中 | 较高 | | LinkdList | 双向链表 | 较高 | 较低 |
Vactor
- Vactor是线程同步的,通过synchronized关键字实现线程安全;
若创建对象时不指定大小第一次扩容为10,后续扩容为原大小的2倍;
ArrayList
ArrayList是线程不安全的;
- 每次添加数据时,进行一次扩容检测,判断是否需要扩容,如果扩容则为原大小的1.5倍。
- 若创建对象时不指定大小,原大小为0则扩容为默认大小10;
- 创建数组时,可指定大小,后续扩容按照指定大小进行扩容;
扩容时会进行修改次数记录,多线程同时修改一个ArrayList的数组元素大小时,会抛出多线程操作异常;
LinkdList
LinkdList是线程不安全的;
- 底层实现了双向链表和双端队列特点;
Set
- 无序的
-
HashSet
底层是HashMap,内部有一个map是HashMap对象,key是传入的对象,value是一个固定的占位对象;
- 内部顺序是固定的,但与添加的顺序无关;
可放一个null,不能放重复值(根据hash()和equals()方法判断是否相同);
TreeSet
底层是TreeMap
无参构造时无序,可通过有参构造函数传入指定排序规则的比较器实现有序;
Map
HashMap
HashMap是线程不安全的;
- 数组加链表实现;
- jdk8中,当一条链表深度达到默认8,整个数组长度达到默认64,会变为红黑树结构,所有链表深度小于6时转为链表;
- 数组的扩容是按原大小的两倍;
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;//辅助变量
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;//当tab为空则创建,长度为16
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);//hash算出的tab下标值为空,存放value
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;//hashcode和equals都为ture,覆盖原来的值
else if (p instanceof TreeNode)//红黑树结构的put
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {//遍历链表看是否有相同的key
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);//没找到相同则存入链尾
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);//扩容或tab长64链表长8则转红黑树
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;//找到相同值覆盖value
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);//LinkedHashMap的扩展方法
return oldValue;//存在相同的key,新值覆盖了原值,返回原值
}
}
++modCount;
if (++size > threshold)
resize();//当tab长度大于阈值则扩容,总长度16则阈值为16*0.75=12,扩容为两倍
afterNodeInsertion(evict);//LinkedHashMap的扩展方法
return null;//key和value添加成功,返回null
}