Collection:
一个集合接口,本身继承了Iterable接口,实现了集合中的一些通用方法,像List、Set等接口是继承它的。
- List:
有序的,可重复的集合
-- ArrayList:
线程不安全,实现了List,底层数据结构是数组,如果不设置初始值默认大小是10,在没有往里面添加数据是一个长度为0的空数组,只有第一次添加数据时才会真正设置默认大小为10,如果我们设置初始容量的话,在没有往里面添加数据也会设置初始容量;在每次用add()方法的时候,会先判断当前数组是否已经满了,满了会进行扩容,每次扩容都会是原来长度的1.5倍。
-- LinkedList:
线程安全,实现了List,底层数据结构是双向链表,因为是链表,所以不存在扩容等机制。
-- Vector:
线程安全,底层原理更ArrayList差不多,只不过在每次扩容时是原来长度的2倍。
ArrayList和Vector:ArrayList是线程不安全的,Vector是线程安全的
LinkedList和ArrayList:LinkedList因为是链表结构,所以它的增删比较快,查询比较慢,时间复杂度为O(n),适合增删多,查询少的操作;ArrayList是数组结构,所以它里面的增删比较慢,get()和set()方法比较快,时间复杂度为O(1),如果查询是以遍历的形式进行的,那么两者之间查询效率是差不多的。
- Set:
无序的,不可重复的集合
-- HashSet:
线程不安全,无序的,不可重复,允许放入null值,但最多只能放入一个null值;底层实际上是调用了HashMap,添加数据时,会先根据添加的元素计算出hashcode值,再根据扰乱算法再加位运算计算出最终要放入的哈希表的位置,放入时会先判断是否有值,无值直接放进去,有值的话会再调用equal()判断是否相等,相等则不放进去,不相等则另找一个空位放进去
-- TreeSet:
有序的,不可重复的,不允许放入null值,底层是调用NavigableMap接口的实现类TreeMap,而TreeMap底层结构是利用红黑树实现的;添加的时候会先调用compare()方法判断是否重复元素。
Map
-HashMap:
线程不安全,JDK8以前的底层结构是数组+链表,JDK8的底层结构是数组+链表+红黑树;当我们没有设置初始容量时,HashMap的默认容量是16,默认负载因子是0.75,一般情况下,建议设置初始容量,不设置负载因子;在进行添加数据时,HashMap会先计算key的哈希值(自定义的),再确定放入那个槽位,放入之前还会先判断是否该槽位是否有值,无值则以该值为头节点创建新链表放入该槽位中,有值则以该值为末节点接在链表中,当数组大于等于64并且该槽位中链表的节点超过8个时,改链表会转化成红黑树进行储存;当HashMap中的元素超过了HashMap的阈值,则会进行扩容,是以翻倍形式进行扩容,比如当前容量为16,扩容后容量变为32;其中key可以作为null值,但只能有一个null值。
-HashTable:
线程安全,不仅实现了Map接口,还继承了Dictionary抽象类,属于比较老旧的类,现在一般很少用到,它里面的哈希值shi直接采用key的hashCode(),而不是自定义的hash;HashTable的默认容量是11,默认负载因子是0.75,每次扩容都是2n+1,比如当前容量是11,扩容后容量变为23;其中key和vaule不能作为null。