List In Java - Java Collections
List is an important data structure in Java, in my mind, it's an extending of array, which supports dynamic resize. On the other hand, a list also may waste some memory data, as it will grow half of current capacity
when the used size reach the capacity.
The following diagram shows the hierachy of the Lists.
The following table lists the comparastion of the Lists.
List | Underlying | Capacity | Thread Safe | Access | Add/Delete |
---|---|---|---|---|---|
ArrayList | Array | Default: 10 Grow: Half of the current size | No | \(O(1)\) | \(O(n)\) |
Vector | Array | Default: 10 Grow: Current size or capacityIncrement | Yes | \(O(1)\) | \(O(n)\) |
Stack | Array | Default: 10 Grow: Current size or capacityIncrement | Yes | \(O(1)\) | \(O(n)\) |
LinkedList | Linked list | No | \(O(n)\) | \(O(1)\) | |
CopyOnWriteArrayList | Array | Default: 0 Grow: 1 Every add operation will create a new array with current size + 1, and copy the data, then assign to the internal array | Yes | \(O(1)\) | \(O(n)\) |
Array Based List
Array based list use an array to save the data, the difference between a list and an array is that list can automatically grow the underlying array if its element size reach its capacity.
-
add an element
-
if need grow the array, the time is \(O(n)\)
It requires to create a new array, and copy the origin data to the new array
-
if no need to grow the array, the time is \(O(1)\)
-
-
insert an element
As requires to move the elements, the time is \(O(n)\)
-
remove an element
- if remove at the end, the time is \(O(1)\)
- if remove requires to move elements, the time is \(O(n)\)
CopyOnWriteArrayList
CopyOnWriteArrayList is thread safe,
-
Write/modification to the list will accquire a lock, but
it will always create a new array, and copy the data to the new array from the old array, as the write operation doesn't impact the old array, so access is not required the lock.
-
Access the list is no lock
LinkedList
LinkedList uses doubly-linked list as its underlying data structure, it has no limitation on the number of the elements to save, and it doesn't require a continous memory to save all the data.
-
add/insert an element
-
if add to the end of insert to the head, the time is \(O(1)\)
-
if add to other location, it needs to traverse the list, so the time is \(O(n)\)
-
-
remove an element
- if remove at the end, the time is \(O(1)\)
- if remove requires to traverse the list, the time is \(O(n)\)
How to choose which list to use?
- If your program requires more random access to the list, you should consider using an array based list.
- If your program requires more add/delete access to the list, you should consider using an linked list based.