图学java基础篇之集合

(本文部分图片引用自其余博客,最后有连接,侵删。因为笔记使用markdown记录,格式可能不是太好看,见谅)html

集合结构


红字为java.util包下的,绿字为concurrent包下扩展的与并发相关的类java

List

ArrayList

功能:有序非线程安全列表
要点:git

  • 底层存储用Object数组
  • 元素可为null
  • 自动扩容至1.5倍
  • 适合随机访问,不适合大量或频繁增删
LinkedList

功能:有序非线程安全列表
要点:github

  • 基于双向链表实现
  • 元素可为null
  • 同时实现了双端队列Deque,支持队列、堆栈操做
  • 适合增删,顺序访问,不适合随机访问
Vector

功能:有序线程安全列表
要点:算法

  • 功能和ArrayList同样,只有线程安全区别,效率较ArrayList低
  • 实际上算是老版本的List,除了线程安全的状况下不用
Stack

功能:基于Vector实现的堆栈
要点:数组

  • 线程安全
  • 后进先出(LIFO)1
CopyOnWriteArrayList

功能:快照版本的ArrayList,修改操做经过复制一份数组操做
要点:安全

  • 线程安全
  • 任何修改都会在拷贝的新副本上进行
  • 修改操做经过ReentrantLock同步
  • 迭代器只能访问,不能修改,且不会由于遍历过程当中修改而抛异常
实现线程安全List的方法
  • 使用synchronized:对List操做是进行同步,须要本身控制
  • 使用Vector:效率低,已经较少使用了
  • 使用CopyOnWriteArrayList,前边已经介绍了,这个只能在量小读多写少的场景下用,且性能不好,通常不要用
  • 使用Collections.synchronizedList():工具类提供的一个比较简便的方法,能够直接建立一个线程安全的list,建议使用。其原理是对ArrayList进行包装,经过一个对象锁来控制并发,须要注意的是要弄清楚对象锁锁的是哪一个对象。

Map

HashMap

功能:
要点:key-value的map,存储位置根据key的hash值肯定markdown

  • 非线程安全
  • 底层使用Entry<K, V>数组table
  • 冲突使用链存储
  • table长度为2^n,这样结合hash算法有利于均匀分布
  • 当发生冲突时,新元素会插入到链首
  • 每次table容量变化时,须要从新rehash
  • 键值都可为null
HashTable

功能:key-value的map,存储位置根据key的hash值肯定,与Hash的算法不一样之处是,其位置直接经过hash(key)%table.length计算(HashMap使用h&(length – 1)计算,效率更高,才外还有一些细节不一样,可自行参看源码)
要点:数据结构

  • 线程安全
  • 继承自Dictionary
  • 底层使用Entry<K, V>数组table
  • 冲突使用链存储
  • table长度为2^n,这样结合hash算法有利于均匀分布
  • 当发生冲突时,新元素会插入到链首
  • 每次table容量变化时,须要从新rehash
  • 键值不能为空
TreeMap

功能:基于红黑树实现的有序集合 要点:架构

  • 非线程安全
  • 底层为一个棵红黑树
  • 继承NavigableMap,主要实现了SortMap,所以是有序的
  • 增删改查均可参考红黑树操做
ConcurrentHashMap

功能:线程安全的HashMap,属于java.util.concurrent下的拓展类
要点:

  • 线程安全
  • 底层实现是一个Segment<K, V>数组,Segment内部经过一个HashEntry<K, V>数组存储元素数据,同时Segment继承了ReentrantLock,直接经过自己的锁对改段数据操做同步
  • 从底层结构能够发现,其修改时不会对整个集合加锁,而是对段加锁,所以容许同时修改多个段,效率更高
  • 继承NavigableMap,主要实现了SortMap,所以是有序的
  • Segment的划分是经过key的hashCode计算
ConcurrentSkipListMap

功能:线程安全的有序Map,是经过一个叫作跳表的数据结构实现 要点:

  • 线程安全
  • 底层实现是一个多层链表,每层元素都有序,每低一层都包含上一层的元素,最底层包含全部元素。这样设计的巧妙之处是从上层逐层查找时,可以快速定位元素区间。思想上有点像折半查找,不过是把每次折半的中间值分层存了起来。同时链表结构是修改操做一样高效
  • key是有序的
  • 空间换时间,效率很高,可是空间占用也很厉害
Map的用法
  • 非线程安全情景基本上都用HashMap
  • 有序用TreeMap
  • 线程安全优先ConcurrentHashMap
  • ConcurrentHashMap和ConcurrentSkipListMap的优劣主要在于并发量,并发量不高时前者效率高,并发量很大时能够考虑后者

Set

HashSet

功能: 就是一个value均为同一个PRESENT对象的HashMap 要点:

  • 非线程安全
  • 底层为一个HashMap,其全部元素value值是一个Object类型的静态常量
  • 其余参考HashMap
TreeSet

功能: 同TreeMap 要点:

  • 非线程安全
  • 底层为一个TreeMap,其全部元素value值是一个Object类型的静态常量
  • 其余参考TreeMap
ConcurrentSkipListSet

功能: 同ConcurrentSkipListMap

CopyOnWriteArraySet

功能: 同ConcurrentSkipListMap
要点:

  • 须要注意的是底层实现是经过CopyOnWriteArrayList,而非HashMap
  • 使用场景与CopyOnWriteArrayList同样

Queue

Queue实现了队列操做,是基本集合的一个扩充,特色是提供了队列操做offer、poll和peek,主要分为两类,一类只支持单端操做,常见的如PriorityQueue,另外一类为双端队列,可实现堆栈操做,均实现Deque。需注意的是队列也提供了add和remove,但应避免使用。

PriorityQueue

功能:如其名,优先级队列,可根据Comparator实现优先级排列
要点:

  • 非线程安全
  • 底层为一个Object数组
  • 不提供Comparator时按照元素天然顺序
ArrayDeque

功能:如其名,优先级队列,可根据Comparator实现优先级排列
要点:

  • 非线程安全
  • 底层为一个E[]数组,同时提供head和tail记录存储数据的首位位置
  • 因为使用数组不是链表,速度比LinkedList更快
LinkedBlockingDeque

功能:阻塞队列,支持支持FIFO和FILO
要点:

  • 线程安全
  • 底层为一个链表,经过一个ReentrantLock锁控制并发
  • 可指定容量,实现阻塞,队满时插入阻塞,队空时读取阻塞,不指定则取最大整数
  • 注意take在空时不阻塞直接返回失败,而poll则会阻塞
  • 可指定元素超时时间
LinkedBlockingQueue

功能:阻塞队列,和LinkedBlockingDeque基本同样,不过支持队列操做

PriorityBlockingQueue

功能:优先级阻塞队列,直接看名字,不解释了

SynchronousQueue

功能:阻塞队列,特殊之处在于其不存储元素,一个元素入队以后必须出队,不然阻塞,能够理解为1个元素的阻塞队列

LinkedTransferQueue

功能:LinkedBlockingQueue和SynchronousQueue的结合体,特色是若是一个元素入队过程当中发现又出队请求,则直接返回,不会再插入链表中 要点:

  • 注意其并发并不是经过ReentrantLock,而是经过LockSupport工具类实现
DelayQueue

功能:延迟队列,只有达到指定时间的元素才能出队
要点:

  • 底层实现是一个PriorityQueue,经过ReentrantLock控制并发
  • 能够理解为一个以入队时间-延迟时间为优先级的队列

一些使用上的浅见

  • 从上边的总结能够看出来java对于集合的实现很是完善,几乎全部场景都有对应的类。所以咱们应该避免重复造轮子,在合适的场景下使用合适的集合不只省力,并且更可靠
  • 能简则不繁,其实多数状况下咱们使用基本的几个类就够了,复杂的实现通常用于底层框架_(如JDK以及一些经常使用框架中就用到了很多并发的实现,但其场景都十分鲜明)_。若是平时写也想上层逻辑时使用了负责的集合类,每每咱们须要认真考虑下真的有没有必要,或者这部分是否是能够抽象为一个通用的组件,这算是个颇有用的代码架构技巧吧。
  • 不管怎么用,理解至上。几个基本类之因此用的顺手是由于咱们熟悉其特性,而对于复杂的集合类必定要理解其特性,不然很容易踩坑。集合部分算是JDK中最容易理解的代码了,花一下子时间而保证优质代码仍是很值的。

备注

一些参考博客 (都是很优秀的博客,若我的看源码吃力,能够参考着这些博客来看)
http://cmsblogs.com/?cat=5
http://my.oschina.net/lifany/blog/191294
http://blog.csdn.net/guangcigeyun/article/details/8278349
http://www.cnblogs.com/skywang12345/p/3503480.html
http://www.infoq.com/cn/articles/java-blocking-queue/
http://my.oschina.net/readjava/blog/282882
http://hyxw5890.iteye.com/blog/1578597

以上xmind图源文件以及该系列相关文件都将同步至github,敬请关注

相关文章
相关标签/搜索