Java的集合框架解析

219 阅读3分钟

image.png 20180825111638257.png

List接口

List接口是一个有序, 元素可重复的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。

ArrayList

底层数据结构是数组,查改快,增删慢。

非线程安全,效率高

Vector

底层数据结构是数组,查改快,增删慢。

线程安全,效率低

LinkedList

底层数据结构是链表,查改慢,增删快。

非线程安全,效率高

Set接口

Set 接口存储一组唯一,无序的对象。

HashSet

底层数据结构是哈希表。(无序,唯一)

依赖两个方法:hashCode()和equals() 保证元素唯一性

LinkedHashSet

底层数据结构是链表和哈希表。(FIFO插入有序,唯一)

1.由链表保证元素有序

2.由哈希表保证元素唯一

TreeSet

底层数据结构是红黑树。(唯一,有序)

如何保证元素排序的呢?

自然排序,比较器排序

Set和List的区别

  1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。

  2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。

  3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

20180825111710146.png

Map接口

Map下主要有HashTable,HashMap,TreeMap。

HashMap

无序,非线程安全,效率高。HashMap允许null值(key和value都允许)

在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。
但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,
这样大大减少了查找时间。

底层实现
首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,
就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,
这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,
同一各链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,
这样大大提高了查找的效率。

当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中

HashTable

无序,线程安全,效率低。除构造函数外,HashTable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。HashTable不允许null值(key和value都允许)。

TreeMap

有序,非线程安全,效率高(O(logN)),但比不上HashMap (O(1))。