List接口
List接口是一个有序, 元素可重复的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
ArrayList
底层数据结构是数组,查改快,增删慢。
非线程安全,效率高
Vector
底层数据结构是数组,查改快,增删慢。
线程安全,效率低
LinkedList
底层数据结构是链表,查改慢,增删快。
非线程安全,效率高
Set接口
Set 接口存储一组唯一,无序的对象。
HashSet
底层数据结构是哈希表。(无序,唯一)
依赖两个方法:hashCode()和equals() 保证元素唯一性
LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一
TreeSet
底层数据结构是红黑树。(唯一,有序)
如何保证元素排序的呢?
自然排序,比较器排序
Set和List的区别
-
Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
-
Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
-
List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
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))。