书接上回,今天说Java中的数据结构,基于Java 11,相关内容点到为止,可能不会太深入。
知道以及够用目的来总结数据结构
将会涉及 Array List Vector Stack Dictionary Set Map Queue Deque
Array
数组最简单的数据结构, 特点可以多维,可object也可基础类型,大小不可变,当然读取和写入速度快。
个人感觉应用场景偏底层,一般不会用于复杂业务数据的处理。与Python中的Array相比,我更喜欢Python(后面开始总结Python,顺手挖坑)
使用很简单,不多说
1 | int[][] array4 = {{1,2,3}, {2,3,4}}; |
List
相比Array,List大家用的应该更多,最多莫过于ArrayList了吧
表,里面的每一个item就像是一行,整个数据就是一个表
List这个Interface的实现有很多,我们最常用的就是 ArrayList,别问我别的,我几乎没有用过其他List实现
出于好奇查了一下ArrayList和LinkedList,网上有很多比较文章,例如:stackoverflow
如果谁在实际工作中使用了LinkedList请告诉我应用场景和理由,感谢先。
多数情况下,简单一句话,用ArrayList 就对了。
CopyOnWriteArrayList 是Arraylist 线程安全的变种,没有用过,作为了解看看,如果以后遇到多线程,应该会优先考虑使用它。
当然,我们还可以用Collections.synchronizedList方法包裹整个对象,实现线程安全,此方式弊端也显而易见,他将锁定整个对象,性能不高。
Vector & Stack
List的近亲,Vector继承了List接口,Stack继承了Vector。元老级对象结构,个人不建议使用。
两个都是线程安全,并通过synchronized关键字进行同步,效率不高
Vector和ArrayList使用上区别不大,Stack主要是实现LIFO
值得注意的是,都是List的实现,所以我们可以这样
1 | List vector = new Vector(); |
记得当年第一份Java工作还在使用Vector,后来就不在用了(暴露了年龄,呵呵)
Dictionary
作为抽象类,它的应用场景应该已经少之又少了吧,感觉可以忽略它了。
与之相关的提一句HashTable吧,线程安全切使用synchronized关键词,方法同步。
HashTable也继承了Map接口,有了ConcurrentHashMap,谁还用HashTable?
Map
这个是个重要的接口,常用实现类超多,键值对的数据结构到处都是。
先说一个最常用的HashMap,无人不知无人不晓,看看他的源码实现应该会收益匪浅
HashMap不是线程安全的,如果再多线程中进行操作,可能会丢失数据哦,为什么,看看HashMap的实现原理你会找到答案的 stackoverflow
如何线程安全,两个方法
ConcurrentHashMap, 大多数人应该首先想到的方法,也是最好的方法
Collections.synchronizedMap(), 还要有这个隐藏方式,不常用,当然是因为性能不佳
还有LinkedHashMap和TreeMap,虽然我基本不用,尤其是TreeMap好像没有用过
三者之间的比较可以看看这个,一目了然。stackoverflow
Map还有什么值得注意,ConcurrentSkipListMap,这个建议要深入研究一下。
Set
这个数据结构的最大特点就是数据不可以重复,实现类也超多
1 | Set hashSet = new HashSet(); |
为了线程安全,和Map相似,有两个方式
CopyOnWriteArraySet,线程安全
Collections.synchronizedSet(); 或者此方法,不建议使用
当然他还有一个重要的类ConcurrentSkipListSet值得研究一下
Queue & Deque
这两个放在一起说,其实有了他们,我们也就彻底废弃了Vector和Stack
- Queue 是FIFO的数据结构
- Deque 是同时支持 FIFO LIFO的数据结构,直接代替带Stack
如何你的数据有顺序要求,并且顺序消费,应该优先考虑Queue。其性能应该更高一些。
我应该认真对比一下Queue与List,看看他们的具体使用区别
说一说常见的实现类
PriorityQueue,可以比较对象权重来进行数据消费
1 | PriorityQueue<Integer> pQueue = new PriorityQueue<>(); |
ArrayDeque,感觉可以代替到LinkedList
LinkedBlockingQueue / LinkedBlockingDeque
以及线程安全的数据结构
ConcurrentLinkedQueue / ConcurrentLinkedDeque
Queue的实现也很多,这个需要点时间好好再挖掘一下,后续有时间我再补充代码
结束语
很多数据类型我们平时并不会用到,但是在某些场合下,只有它最合适,所以还是需要了解一下以备不时之需。
下一个目标是什么呢? Java中的时间好啦,应该比较简单
P.S. Python的总结也该开始了(挖坑,督促自己填)