这篇文章主要是自我回归并和大家分享一下Java常用的数据结构,以及各自数据结构所具有的特点。废话不多说,我们直接开始。
Java中有几种常用的数据结构,主要分为Collection和map两个主要接口,我们从源码中探索一下各个接口,以及接口的实现。
Collection接口
Map接口
梳理清楚逻辑关系我们主要将从、数据结构、存储结构、线程是否安全、特点等方面进行比较说明。
ArrayList
- 数据结构:ArrayList底层使用的是Object数组
- 存储结构:物理存储单元上连续的存储结构。
- 线程是否安全:ArrayList是线程不安全的。
- 特点:既然是一串连续的存储结构,所以方便查找。但是要做新增和删除操作的时候,是要有移动位置的操作。所以ArrayList适用于存储,查询操作比较频繁的数据存储。为什么ArratyList是线程不安全的,因为ArrayList是非同步的,具体看源码(ArrayList的方法是没有加锁的,例add())
LinkedList
- 数据结构:LinkedList底层使用的是双向循环链表数据结构
- 存储方式:物理存储单元上非连续、非顺序的存储结构。
- 线程是否安全:LikedList也是线程不安全的(有兴趣的可以去看一下LinkedList的源码)
- 特点:既然链表在物理存储单元上是非连续的,并且链表要拿出一部分空间去存储直接后继和前驱,所以每一个元素消耗的空间要比ArrayList大。并且由于它的存储结构,导致他的查询不是很方便,需要去遍历每一个节点,然后查找该节点后继节点。不适合存储需要大量查询操作的数据存储,但他的插入就比ArrayList方便,不需要进行换位操作。只需要改变指针前驱和后继。
Vector
- 数据结构:Vector底层使用的是Object数组。
- 存储结构:物理存储单元上连续的存储结构。
- 线程是否安全:Vector是线程安全的。(Vector类的方法都是有锁的,例add())
- 特点:Vector是线程安全的,可以由多个线程访问一个Vector对象。但当一个线程访问的话,保证线程安全势必会消耗一定的资源(鱼与熊掌不可兼得啊)。一个线程访问就无需考虑是否线程安全的问题,建议使用ArrayList。
TreeSet
- 数据结构:底层数据结构是二叉树
- 线程是否安全:不保证线程安全的
- 特点:有序的,并且没有重复元素。可以指定一个顺序。
HashSet
- 数据结构:(链表和红黑树(jdk1.8以后))
- 线程是否安全:不保证线程安全的
- 特点:元素没有顺序(因为底层用的是HashMap,HashMap本身中的元素度没有顺序)、元素不能重复。
HashMap
- 数据结构:(链表和红黑树(jdk1.8以后))
- 存储结构:
- 线程是否安全:非线程安全
- 特点:Null可以做主键,但只能有一个,可以有多个Value为Null。适用于在Map中插入、删除和定位元素。
TreeMap
- 数据结构:树
- 存储结构:
- 线程是否安全:非线程安全
- 特点:有序的,适用于按自然顺序或自定义顺序遍历键(key)。
LinkedHashMap
- 数据结构:HashMap+LinkedList
- 存储结构:
- 线程是否安全:非线程安全
- 特点:有序、Key和Value都允许空、Key重复会覆盖、Value允许重复
PS:这篇也是最近开始回顾知识点的第一篇,如有不正确的地方还请指正。很多数据结构的特性,再起设计(数据结构以及存储结构)上已经决定了,所以还是建议大家无事的时候多看看源码。