常用集合特性
1. ArrayList特性
不唯一,有序
:实现了List接口,该接口是序列,所以不唯一且按顺序保存不同步
:因为ArrayList.add()没有synchronized同步锁控制扩容机制
:初始化默认为10,每次数组容量的增长大约是其原容量的 1.5 倍底层结构
:数组 private transient Object[] elementData;
2. LinkedList特性
不唯一,有序
:实现了List接口,该接口是序列,所以不唯一且按顺序保存不同步
:因为LinkedList.add()没有synchronized同步锁控制扩容机制
:链表没有扩容机制底层结构
:链表
3. Vector特性
不唯一,有序
:实现了List接口,该接口是序列,所以不唯一且按顺序保存同步
:Vector是同步的,因为方法都有synchronized修饰扩容机制
:链表没有扩容机制底层结构
:Vector底层数据结构是动态数组
4. HashSet特性
唯一的,无序
:底层是HashMap,继承了HashMap的唯一的,无序的不同步
:因为add()方法没有添加同步锁synchronized扩容机制
:默认初始容量是16,加载因子是0.75,扩容为原来的2倍底层结构
:HashMap
5. HashMap特性
唯一的,无序
:键唯一,经过Hash函数,所以元素是打乱存放的不同步
:因为add()方法没有添加同步锁synchronized扩容机制
:默认初始容量是16,加载因子是0.75,扩容为原来的2倍底层结构
:HashMap
实现线程同步
使用 Collections.synchronizedList() 方法
//这里只是对ArrayList举例,其他都是一样的
List<String> list = Collections.synchronizedList(new ArrayList<String>());
list.add("practice");
list.add("code");
list.add("quiz");
synchronzied(list) //对变量上锁
{
Iterator it = list.iterator();
while (it.hasNext())
System.out.println(it.next());
}
Map深层解析
1. Map数据结构
“数组+链表+红黑树”,
当数组元素小于64时,当链表结点大于8会优先考虑将数组扩容。
当数据元素大于64时,当链表结点大于8会转为红黑树,当红黑树结点小于6会转为链表。
2. Map put过程
- 首次扩容:
先判断数组是否为空,若数组为空则进行第一次扩容(resize); - 计算索引:
通过hash算法,计算键值对在数组中的索引; - 插入数据:
如果当前位置元素为空,则直接插入数据;
如果当前位置元素非空,且key已存在,则直接覆盖其value;
如果当前位置元素非空,且key不存在,则将数据链到链表末端;
若链表长度达到8,则将链表转换成红黑树,并将数据插入树中; - 再次扩容
如果数组中元素个数(size)超过threshold,则再次进行扩容操作。
3. HashMap为什么线程不安全?
HashMap在并发执行put操作时,可能会导致形成循环链表,从而引起死循环。
参考文章:死循环如何产生的
4. HashMap、HashTable、ConcurrentHashMap
HashMap:线程不安全、性能高
Hashtable:线程安全、性能低
ConcurrentHashMap:线程安全、性能中
5. LinkedHashMap
LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能。但因为它以链表来维护内部顺序,所以在迭代访问Map里的全部元素时将有较好的性能。