平常常用到的Java集合类,先上一张抄来的图
Java集合框架主要包括两种类型的容器,一种是集合(Collection),另一种是图(Map)
Map以键值对的方式存储数据,常用的有四种实现类HashMap,Hashtable,linkedHashMap,ConcurrentHashMap.
HashMap:
- 线程不安全,但效率较高,Key和Value都可为空
- 它的底层实现是数组+链表,JDK1.8之后链表变成红黑树;初始内存大小为16,一般是元素总数到达大小的一半的时候进行扩容。(划重点,面试要考!!!)
- map的数组也叫哈希桶,计算哈希桶的方式是通过位运算;如果有人问你为什么不取模的话,你就说位运算快啊(位运算是计算机底层的01计算)
HashTable:
- 线程安全,但效率较低,key和value不可以存储null
- 它的底层实现是数组+链表,初始大小为11
- 为 线程安全而生的一个实现类但是有比他性能更好的实现类出现了
ConcurrentHashMap:
- 线程安全,效率比HashTable高;key和value不可以存储null
- 它的底层实现是分段数组+链表,Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍
linkedHashMap和TreeMap:
都有排序功能但是TreeMap默认是升序的,linkedHashMap是根据插入的顺序来维护数据的有序性
List列表,常用的有三种实现类ArrayList,LinkedList,CopyOnWriteArrayList
ArrayList:
- 以数组的方式存储数据,数组在磁盘占用的存储空间是连续的,所以读取和修改效率高但增加删除效率低
- 创建ArrayList的时候会有一个数组默认大小,如诺元素超过了数组数组容量则创建一个更大容量的数组并将当前数组的元素全部复制到新的数组当中
ArrayList:
- 以链表的方式存储数据,所以查询以及修改都需要从头遍历链表所以查询和修改的效率较为低下;但是由于链表的特性增加以及删除元素的效率很好并对空间的利用率足够高;节省了ArryList的扩容操作降低CPU消耗
CopyOnWriteArrayList:
- CopyOnWriteArrayList,是一个线程安全的List接口的实现,它使用了ReentrantLock锁来保证在并发情况下提供高性能的并发读取。
Set最大的不同是Set内的元素不重复
HashSet:
- 散列集HashSet是一个用于实现Set接口的具体类,可以使用它的无参构造方法来创建空的散列集,也可以由一个现有的集合创建散列集。在散列集中,有两个名词需要关注,初始容量和客座率。客座率是确定在增加规则集之前,该规则集的饱满程度,当元素个数超过了容量与客座率的乘积时,容量就会自动翻倍。
LinkedHashSet:
- LinkedHashSet是用一个链表实现来扩展HashSet类,它支持对规则集内的元素排序。HashSet中的元素是没有被排序的,而LinkedHashSet中的元素可以按照它们插入规则集的顺序提取。
TreeSet:
- TreeSet扩展自AbstractSet,并实现了NavigableSet,AbstractSet扩展自AbstractCollection,树形集是一个有序的Set,其底层是一颗树,这样就能从Set里面提取一个有序序列了。在实例化TreeSet时,我们可以给TreeSet指定一个比较器Comparator来指定树形集中的元素顺序。树形集中提供了很多便捷的方法。
CopyOnWriteSet:
- CopyOnWriteSet,是一个线程安全的Set接口的实现,它使用了ReentrantLock锁来保证在并发情况下提供高性能的并发读取。