Collection集合
Collection
List
ArrayList
ArrayList:非线程安全
原理:数组 ---- 使用Object[]数组来存储元素
性质:查询效率高,增加效率低;当不考虑查询效率或元素个数少的时候可以使用ArrayList;
LinkedList
LinkedList:非线程安全
原理:双向链表
性质:查询效率低,增加效率高;当出现大量添加而不需要大量的查询的时候可以考虑使用LinkedList;可以通过get(index)方法获取元素,LinkedList,有first与last成员变量,代表第一个元素和最后一个元素,当通过get进行查询时,先会比较在前半段还是后半段,若在前半段,将通过first节点依次向后进行遍历,若在后边半段,将通过last节点依次向前遍历(双向链表);
Vector
Vector:线程安全(synchronize方法锁)
原理:与ArrayList原理相同,在此基础上加上了synchronzed的方法锁
性质:synchronzed的方法锁导致Vector的锁粒度太大,在并发场景下,效率很低所以基本没有使用情况
Stack
Vector:线程安全(synchronize方法锁)
原理:在Vector的基础上封装了push与pop方法
性质:与Vector相同
CopyOnWriteArrayList
CopyOnWriteArrayList:线程安全(ReentrantLock,使用了可重入锁)
原理:写时复制技术,在添加的时候会创建一个原来的副本,以供读操作
Set
HashSet
HashSet:非线程安全
原理:本质上还是HashMap,维护了一个HashMap<T, Object> map;
性质:不存在相同的元素,且查询与添加的效率较高;
TreeSet
TreeSet:非线程安全
原理:红黑树——通过构造函数可以知道TreeSet其实就是在维护TreeMap
看下面add()方法,其实调用的就是构造函数创建的TreeMap
构造函数里创建的TreeMap赋值给了成员变量m,而add方法调用的m的put方法,添加我们放进去行参数赋值给了Key,而Value是PRESENT也就是提前new好的公用Object,每次添加时,就将这个是先准备好的Object对象放进Value值里
性质:每次添加元素时,会找到一个叶子结点去存放,但当树出现不平衡的情况下,需要进行平衡,查询效率相对较高,添加效率一般(主要原因在于树的平衡)
CopyOnWriteArraySet
CopyOnWriteArraySet:线程安全(ReentrantLock,使用可重入锁保证线程安全)
原理:写时复制技术,在添加的时候会创建一个原来的副本,以供读操作
Map
HashMap
HashMap:非线程安全
原理:数组+链表+红黑树(JDK1.8后)、数组+链表(JDK1.7)
性质:以牺牲空间来换取时间,每个元素以键值对的方式进行存储;添加元素时,会先计算哈希值进行位运算找到对应的桶位,若桶位以有元素,将以链表的方式存在相同的桶位下,当冲突严重链表的长度达到8时进行树(红黑树)化;若元素个数达到集合容量的75%时(装填因子0.75),将会触发扩容机制;
LinkedHashMap
LinkedHashMap:非线程安全
原理:数组+链表+红黑树+双向链表(JDK1.8后)、数组+链表+双向链表(JDK1.7)
性质:在继承HashMap的数据结构基础上多了双向链表,保持快速查询,还具有添加顺序与,遍历顺序相同的性质
TreeMap
TreeMap:非线程安全
原理:红黑树
性质:继承于SortedMap接口,性质与红黑树性质相同;需要我们实现Comparable接口的实现类,提供比较规则;
Hashtable
Hashtable:线程安全(synchronize方法锁)
在官方注释里说,Java集合框架与新的集合实现不同,{@code Hashtable}是同步的。如果不需要线程安全的实现,建议使用{@link HashMap}代替{@code Hashtable}。如果需要一个线程安全的高并发实现,那么推荐使用{@link java.util.concurrent.ConcurrentHashMap}代替{@code Hashtable}
因此,当选择使用Hashtable不需要线程安全时,可以选择使用HashMap;在高并发的情况下可选择ConcurrentHashMap
ConcurrentHashMap
ConcurrentHashMap:线程安全(Unsafe类+synchronize对象锁)
原理:和HashMap相同,在此基础上增加锁机制,解决高并发场景的数据安全问题
性质:与HashMap相同,但与Hashtable在锁机制方面不同,ConcurrentHashMap使用Unsafe类提供的CAS(乐观锁 | 自旋锁)和synchronize对象锁,减少了锁的粒度,而Hashtable使用synchronize方法锁,当同时调用put方法时,需要等另一个线程执行完毕时释放锁,才能再次执行put方法;