Article Directory
ArrayList
ArrayList is an array queue, equivalent to a dynamic array.Compared to arrays in Java, its capacity can grow dynamically.It inherits from AbstractList and implements List, RandomAccess, Cloneable, java.io.Serializable interfaces.The default capacity is 10 (you can see from the source that each capacity expands by 1.5 times, int newCapacity = oldCapacity + (oldCapacity > > 1);).Operation in ArrayList is not thread safe!Therefore, it is recommended that ArrayList be used in a single thread, while Vector or CopyOnWriteArrayList can be selected in a multi-threaded environment.
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { ...... /** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } ...... }
CopyOnWriteArrayList
CopyOnWriteArrayList has the following features:
- List interface is implemented;
- Holds a ReentrantLock lock = new ReentrantLock();
- Copy a new array when adding, and assign it to the array after insertion, modification, or removal.
- All additions and deletions require locks, and only one lock, while read operations do not require locks to support concurrency.Why do I need to create a new array in addition or deletion, and assign it to the original reference after the operation is complete?This is to ensure that elements are available when get ting, and if the original array is modified directly during the process of adding or deleting, it may result in data not being available when performing a read operation.
- Use ReentrantLock internally to keep threads safe;
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; /** The lock protecting all mutators */ final transient ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private transient volatile Object[] array; public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } } } ...... }
Vector
Vector s are thread-safe, as you can see from many synchronized sources.
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { ...... protected Object[] elementData; protected int elementCount; protected int capacityIncrement; public Vector(int initialCapacity) { this(initialCapacity, 0); } public Vector() { this(10); } public synchronized int capacity() { return elementData.length; } public synchronized int size() { return elementCount; } ...... }
LinkedList
LinkedList implements the List interface as well as Array List, but LinkedList is implemented using a chain list.
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { transient int size = 0; transient Node<E> first; transient Node<E> last; public LinkedList() { } private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } ...... }
The difference between ArrayList and LinkedList:
- ArrayList is based on arrays and LinkedList is based on chained lists
- ArrayList random access and modification is more efficient, LinkedList insertion and deletion is more efficient
The Vector Difference of ArrayLis
- Vector is thread safe, there are many synchronized sources that can be seen, but ArrayList is not.Causes Vector efficiency to be inferior to Array List;
- Both ArrayList and Vector use linear continuous storage space. When there is not enough storage space, ArrayList increases by default by 1.5 times and Vector by default by 2 times.
- Vector can set capacityIncrement, but ArrayList cannot. Literally, it is capacityCapacity, Increment increase, parameter of capacity increase.
Related links: The difference between ReentrantLock and synchronized