1.ArrayList源码

采用数组,初始化容量10,扩容是一倍,也可以指定扩容的数量,采用Fast-Fail机制。 jdk8中初始化的时候是0,第一次add的时候扩容到10。 查找快速,增删慢

2.LinkedList

采用带头尾指针的双向链表结构,

3.HashSet

底层是hashMap,元素存放在key上。

4.LinkedHashSet

继承与HashSet、又基于LinkedHashMap来实现的。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接列表,保证该迭代顺序可为插入顺序或是访问顺序。

5.HashMap

jdk7:key-value键值对,采用数组+链表结构,通过key的hashcode找到桶的下表(通过h&length-1)得到,这个&比取模更快,效果一样,如果下标为空,直接放进去,否则再通过key的equal方法判断,再下标的链表中,如果相同,替换原来的value,否则,放入链表之中,map的初始容量是16,加载因子是0.75,当map中的元素个数容量超过16*0。75即12之后(不是占用桶的个数),桶扩容成原来的一倍即32,这样容量都是2的幂次方,在hash取模的时候能尽量均匀的分布(幂次方地位都是0,与的时候才能让每个位置都能使用),map的Fail-Fast快速失败机制:对map的修改操作,通过增加volatile类型的modCount变量,在迭代器初始化的时候把这个变量值复给迭代器的expectedModCount,当两个不相等的时候就抛出异常,这样保证多线程操作时不会出问题。

jdk8:大致和上面差不多,只是链表采用了链表+红黑树,这样当链表中元素过多,提高性能,防止出现o(n)的时间效率,当链表中元素个数超过8时,链表就转换成红黑树,个数低于6的时候就变回链表,采用二次hash,这样保证高低位都能使用到,尽量平均元素的位置。另一个优化:扩容之后,重新计算元素的位置,扩容是两倍,也是桶容量高一位增加一个1,所以jdk8中,通过判断key的hash与之对应的高一位是1还是0,1也就是移动到旧位置+旧容量的位置上,0就是不用移动,因为hash取&得时候1和0与的结果是0.

6. LinkedHashMap

LinkedHashMap实继承HashMap,不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。

7.HashTable

初始容量11,加载因子0.75,和hashmap不同之处,方法都是synchronized,不能插入null值。