ArrayList — array-based, fast random access. LinkedList — linked-list-based, fast insert/delete at ends.
Analogy: ArrayList is like a numbered apartment building — go straight to apartment #50. LinkedList is like a chain of rooms — you must walk through each room to reach the 50th one.
ArrayList:
Object[]).1ArrayList<String> list = new ArrayList<>();23list.add("Alice"); // O(1) — append4list.add("Bob");5list.add(1, "Charlie"); // O(n) — shifts elements67String first = list.get(0); // O(1) — instant8String third = list.get(2); // O(1) — instant910list.remove(1); // O(n) — shifts elements1112// Pre-size for performance:13ArrayList<Integer> big = new ArrayList<>(10000);
LinkedList:
1LinkedList<String> linked = new LinkedList<>();23linked.add("Alice"); // O(1) — append at tail4linked.addFirst("Bob"); // O(1) — add at head5linked.addLast("Charlie"); // O(1) — add at tail67String first = linked.get(0); // O(n) — must traverse!89linked.removeFirst(); // O(1)10linked.removeLast(); // O(1)1112// Deque operations:13linked.push("item"); // O(1) — stack14linked.pop(); // O(1) — stack15linked.offer("item"); // O(1) — queue16linked.poll(); // O(1) — queue
Complexity comparison:
get(index): ArrayList O(1), LinkedList O(n)add(end): Both O(1)add(middle): ArrayList O(n), LinkedList O(1) if you have the noderemove(middle): ArrayList O(n), LinkedList O(1) if you have the nodecontains(): Both O(n)When to use:
Common mistake: Choosing LinkedList for frequent index access — it's actually slower than ArrayList due to poor cache locality.