Linked Structures and Pointers
ArrayList and LinkedList implement the same List operations but store items differently: a growing contiguous array versus nodes joined by pointers.
Why Two Classes Hold the Same Kind of Sequence
Suppose you need to keep an ordered collection of items in a program: a playlist, a queue of print jobs, or a row of records loaded from a file. Java provides more than one class that can hold such a sequence. Two of the most common are java.util.ArrayList and java.util.LinkedList. Both implement the same List interface, so they share the same set of operations, and a program can often call the same methods on either one.
Yet the two classes behave very differently in speed, and that difference is the reason both exist. The underlying question is this: if the operations are identical, why not build one list class? The answer is that no single internal design makes every operation fast. Each design makes some operations cheap and others expensive. So the practical skill is not memorizing which class is better. It is recognizing which operations your program will repeat most often, and then picking the design that makes those operations cheap.
What do you think happens?
Both classes expose the same methods. Which one would you expect to be faster when your program repeatedly asks for the item at position 7?
Reveal answer
ArrayList
An ArrayList keeps its items in one contiguous block, so it can locate slot 7 directly. A LinkedList has to follow pointers from the first node through several nodes before reaching position 7. The sections below trace exactly why.
How an ArrayList Lays Out Its Items
An ArrayList keeps its items in one contiguous block of storage, behaving like a row of numbered slots. Slot 0 holds the first item, slot 1 holds the second, and so on. The row can grow: when it fills up, the list obtains a larger row and copies the items across. From the programmer's point of view you simply keep adding items and the list takes care of the growing. Internally, though, the items sit side by side, and that arrangement is what makes positions so easy to compute.
The important feature is adjacency. Slot 2 sits directly after slot 1 in the same block, so the list does not need to examine slots 0 and 1 to know where slot 2 is. Keep this picture in mind, because the rest of the comparison follows from it.
Nodes and Pointers in a LinkedList
A LinkedList takes a completely different approach. Instead of one block of adjacent cells, it stores each item in its own small container called a node. Every node holds an item and also a pointer, meaning a reference, to the next node in the sequence. The list itself only needs to remember where the first node is. Everything after that is reached by following the pointers from one node to the next.
A node is a small container that holds one item and a pointer (a reference) to the next node in the sequence. A linked structure is a collection of such nodes in which the pointers, rather than physical adjacency, define the order of the items.
Because the nodes are not required to sit next to each other, they can be scattered anywhere. What holds the sequence together is the chain of pointers. Picture a node holding value A whose pointer leads to a node holding B, whose pointer leads to a node holding C, and so on. The end of the chain is the last node, which has no next node to point to.
This arrangement is the key to the LinkedList's strengths and weaknesses. Changing where one node points is a local change that does not disturb the rest of the chain. Finding a node, on the other hand, requires walking the chain one link at a time.
Reaching Position k in Each Structure
Random access means getting or changing the item at a specified position k. Whenever a program asks for the item in slot 7, or wants to overwrite the item at position 12, it is doing random access. This is where the two structures diverge most sharply.
For an ArrayList, random access is essentially immediate. The list knows exactly where slot k lives because the cells are contiguous, so the time needed does not depend on how many items the list holds. This is written Theta(1), a constant amount of work. Slot 7 costs about the same as slot 0.
For a LinkedList there is no shortcut. To reach position k, the program must start at the first node and follow pointers forward k times. Picture a LinkedList holding A, B, C, D, E, F, G, H. To reach H at position 7, the walk goes: start at the first node (A), follow to B, follow to C, follow to D, follow to E, follow to F, follow to G, and follow once more to H. That is seven pointer follows. A position near the front is reached quickly, while a position near the back takes a long walk. The work grows with k, which is written Theta(k).
Inserting in the Middle: Shifting Versus Relinking
Changing the middle of a list is where the LinkedList earns its place. Consider what it takes to insert a new item between two existing items. In an ArrayList, the new item needs a free slot at the correct position, so every item from that point onward must move one position to make room. The cost depends on how many items sit after the insertion point. Inserting at the beginning forces the most movement, because every item shifts. Writing this cost as Theta(n) means the time grows in step with the number of items n.
In a LinkedList, the same insertion is a matter of re-pointing a few links. The new node is created, its pointer is set to the node that should follow it, and the pointer of the node before it is changed to point to the new node. Inserting X between A and B means setting X's pointer to B and changing A's pointer to X. Nothing else moves. A handful of pointer updates is enough regardless of how long the list is. That is why these changes take Theta(1) time once the program is already standing at the spot where the change belongs.
Mistakes When Choosing a List
Common mistake Assuming LinkedList is always faster for insertions
What it looks likeAdding a new item at the front of a large list in a loop, then assuming the LinkedList will be cheap because it is a linked structure.
Why it failsInsertion is constant time only once the program is already at the right spot. If the program has to walk k nodes to find the position, the search cost of Theta(k) is paid before any relinking happens.
Do this insteadCount the whole operation, including locating the position, before deciding which structure is cheaper.
Common mistake Assuming ArrayList insertion is always slow
What it looks likeAppending items to the end of an ArrayList in a loop and expecting each append to shift everything.
Why it failsAdding at the end is efficient for both classes. An
ArrayListappends into the next free slot, so no existing items move.Do this insteadSeparate the costly case, inserting or removing in the middle, from the cheap case, appending at the end.
Common mistake Choosing a structure by memorizing which class is better
What it looks likePicking LinkedList because it sounds more advanced for a program that mostly reads items by index.
Why it failsNo single internal design makes every operation fast. The right choice depends on which operations the program repeats most.
Do this insteadList the operations your program repeats most often, then choose the structure that makes those cheap.
Common mistake Forgetting that a LinkedList must walk from the first node to reach any position beyond the front
Matching the List to the Workload
| Operation | ArrayList | LinkedList |
|---|---|---|
| Get or set item at position k | Theta(1), direct slot computation | Theta(k), walks k nodes from the first node |
| Insert or remove in the middle | Theta(n), later items shift | Constant time once the node is located, found by walking |
| Add at the end | Efficient, fills the next free slot | Efficient, attaches after the last node |
| Sorting the items | Efficient | Efficient |
| Internal storage | One contiguous block that grows | Nodes joined by pointers |
Operation costs for the two List implementations, as described in the source.
Read this table against your own program. If the work is dominated by reading items by position, such as looking up slot 7 many times, the ArrayList's constant-time access is the decisive advantage. If the work is dominated by inserting or removing in the middle of the sequence, the LinkedList's cheap relinking is the advantage. If the work is mostly appending and sorting, both classes perform well, and other design choices will probably matter more than this one.
Practice Choosing a Structure
A program keeps a queue of print jobs. Jobs are appended at the back, and the program frequently removes a job from the middle when a user cancels it. It rarely reads jobs by position. Which list type would you choose, and what operation's cost drives your decision? Explain your reasoning in terms of the cost of finding the position and the cost of changing the list.
Hints
- Think about which operation dominates: appends, reads by index, or removals from the middle.
- Removal from the middle in an
ArrayListmeans later items must shift, costing Theta(n). - In a
LinkedList, a removal costs little once the node is found, but finding a node in the middle still requires a walk.
Explain, without looking back, why get(0) costs about the same on an ArrayList holding a million items as on one holding ten items, but get(999999) on a LinkedList costs far more than get(0).
Hints
- Consider whether the
ArrayListmust visit earlier slots to find slot k. - Consider how many pointer follows the
LinkedListneeds to reach the front versus the far end.
Key Takeaways
- An
ArrayListstores items in one contiguous, growing block of numbered slots, so reading or writing position k is constant time, Theta(1). - A
LinkedListstores each item in a node holding a value and a pointer to the next node, so reaching position k means walking k nodes, Theta(k). - Inserting or removing in the middle is costly for an
ArrayList, Theta(n), because later items shift, while aLinkedListcan relink a few pointers in constant time once the position is found. - Appending and sorting are efficient for both classes, so choose the structure by which operations your program repeats most often.