ArrayList and LinkedList
One List — different internals
ArrayList and LinkedList implement the same
List interface, so many of their operations look identical from the outside.
The difference starts inside: data is stored differently, which means different operations have different costs.
ArrayList: a dynamic array
ArrayList stores elements in an array that is replaced by a larger one when necessary.
Because of this, reading or replacing an element by index is fast: the required position can be calculated directly.
List<String> names = new ArrayList<>();
names.add("Ann");
names.add("Bob");
names.add("Cara");
System.out.println(names.get(2)); // Cara
Appending is usually fast. But inserting or removing near the beginning or middle may require shifting many elements. Growing the internal array also occasionally requires copying, so the cost of one particular append can differ from the usual case.
LinkedList: a chain of nodes
LinkedList stores elements in nodes connected to their neighbors.
To reach an arbitrary index, it has to walk through the chain,
so frequent get(index) calls are not its strength.
LinkedList<String> queue = new LinkedList<>();
queue.addLast("first");
queue.addLast("second");
queue.addFirst("zero");
System.out.println(queue.getFirst()); // zero
Once the required node is already known, neighboring nodes can be linked or unlinked without shifting the rest.
But this does not mean that LinkedList is automatically faster for every insertion in the middle:
finding the position itself may take linear time.
What to choose by default
For most ordinary lists, ArrayList is a sensible starting point:
it stores data compactly, works well with indexes, and usually provides predictable performance.
Choose LinkedList when its model genuinely matches the operations you need,
not simply because its name says “linked.”
List.
Switching implementations will be easier when the rest of the code does not depend on their special methods.