List

List

ArrayList

1.底层由动态数组实现

2.扩容方法为,需要扩容的时候,扩容1.5倍,如果1.5倍还不够,就以需要扩容的容量来扩容,创建新的数组,并将老数据拷贝到新数组中。

3.线程不安全,如果想线程安全,使用CopyOnWriteArrayList或者SyncornizedList,或者Vector

4.通过重写writeObject方法,进行序列化

5.支持求并集(addAll),交集(retainAll),单向差集(removeAll)

平均时间复杂度

插入 平均 O(n),队尾O(1)

查找 平均 O(1)

删除 平均 O(n),队尾O(1)

LinkedList

1.底层由链表组成

2.具有双向链表的特征,可以实现栈,队列的功能,队列(addLast, removeFirst),栈(addFirst, removeFirst);

3.线程不安全,需要线程安全要使用ConcurrentLinkedQueue

CopyOnWriteArrayList

1.ArrayList的线程安全版本,读不加锁,写加锁。

2.为什么读不加锁,因为写的时候,是拷贝新的数组进行修改,修改完毕后再修改原数组的引用,此时如果并发读,读的是旧数组。

3.如果写不加锁会出现什么问题?会导致并发写入的时候,有写入丢失,

4.为什么要采用这种写入拷贝新数组的方式?因为如果不这么做,直接在原数组上修改,那并发读的时候,可能会读到脏的数据。

5.真正存储数组的字段使用了volatile,保证了对数组的修改,其他线程立马可见。

6.缺点,写入的时候需要拷贝一份数组,会导致占用内存比较多。

7.写入的性能都比较差,需要O(n),查找很快,适合读多写少的场景。