Java常用集合底层数据结构

497 阅读2分钟

集合是我们在开发中很常见的容器,当我们需要保存一组数据类型相同的数据的时候,就需要用到一个容器来存储,这个容器就是数组,但是使用数组存在着一定的弊端,因此就有了集合这个概念。集合同样也是用来存储多个数据,在Java中,集合用来存储不同数量不同类型的对象和具有映射关系的数据。

数组的缺点:
一、声明之后,长度将不可改变。
二、声明数组数据类型之后决定了数组能够存放的数据类型。
三、数组存储的数据是有序、可重复。

开发中最常见的集合是(接口)List、Set、Map,而这三个接口又有了各自对应的实现类。

ListArrayListLinkedListVector
SetHashSetLinkedHashSetTreeSet
MapHashMapLinkedHashMapTreeMapHashTableConcurrentHashMap

接下来是他们底层数据结构的实现。

ArrayList:底层使用Object[]存储。

LinkedList:底层数据结构是双向链表(jdk1.7之前使用双向循环链表,jdk1.8开始取消循环)

Vector:使用Object[]存储。

HashSet:底层使用HashMap保存数据。

LinkedHashSet:继承HashSet的子类,底层使用LinkedHashMap保存数据。

TreeSet:底层数据结构是红黑树。

HashMap:jdk1.7之前底层数据结构是数组+链表(其中数组是主题,链表是为了解决hash冲突),jdk1.8之后是数组+链表/红黑树
(当链表长度达到阈值后,如果数组长度没达到默认值,则会按照2n对数组进行扩充;如果数组长度超过默认值,则会转为红黑树)。

LinkedHashMap:继承HashMap的子类,底层数据结构跟HashMap相似,但多了一条双向链表,用于顺序插入数据。

TreeMap:底层数据结构是红黑树(实现了某个接口,赋予了排序和搜索的能力)。

HashTable:底层数据结构是数组+链表(线程安全但不建议使用,因为他是使用同一把锁来保证线程安全,效率低下且容易进入阻塞或轮询状态)。

ConcurrentHashMap:jdk1.7之前底层数据结构是数组+链表(其中数组是主题,链表是为了解决hash冲突),jdk1.8之后是数组+链表/红黑树
(当链表长度达到阈值后,如果数组长度没达到默认值,则会按照2n对数组进行扩充;如果数组长度超过默认值,则会转为红黑树)

多线程下使用ConcurrentHashMap的原因:

jdk1.7通过segment+hashentry数据结构保证线程安全,将数据分为一段一段存储,并且给每一段数据配上一把锁,当一个线程占用所访问一个段数据的时候,其他的段数据也能被访问;
jdk1.8之后,摒弃了segment锁,而是通过CAS+synchronized关键字来保证线程安全。

以上内容可能存在不足或错误,如有发现请指出来。