Start from the question you need to answer fast
| If you mostly need to… | Use | Cost |
|---|---|---|
| read/write by position | array, ArrayList | O(1) |
| add/remove at the end | ArrayList | O(1) |
| add/remove at both ends | ArrayDeque | O(1) |
| undo / last-in-first-out | ArrayDeque as a stack | O(1) |
| serve in arrival order | ArrayDeque as a queue | O(1) |
| check “have I seen this?” | HashSet | O(1) average |
| look up a value by key, count things | HashMap | O(1) average |
| keep things sorted, find nearest | TreeSet, TreeMap | O(log n) |
| always get the smallest/biggest next | PriorityQueue | O(log n) |
| model connections | adjacency list ArrayList<ArrayList<Integer>> | O(n + m) memory |
| track merging groups | union-find (two small methods) | ≈ O(1) |
A worked example
“A website gets page visits as a stream. At any moment, tell me the most visited page; when two tie, the one that comes first alphabetically.”
- “How many visits per page?” → a
HashMap<String, Integer>for counting. - “The most visited” → keep a running best while counting (or a
PriorityQueueif pages can also lose visits).
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
String[] visits = {"home", "blog", "shop", "blog", "home", "blog", "shop", "shop"};
HashMap<String, Integer> count = new HashMap<String, Integer>();
String top = null;
for (String page : visits) {
int c = count.getOrDefault(page, 0) + 1;
count.put(page, c);
int best = top == null ? 0 : count.get(top);
if (c > best || (c == best && page.compareTo(top) < 0)) top = page;
System.out.println("after " + page + ": top is " + top + " (" + count.get(top) + ")");
}
}
}Output
after home: top is home (1) after blog: top is blog (1) after shop: top is blog (1) after blog: top is blog (2) after home: top is blog (2) after blog: top is blog (3) after shop: top is blog (3) after shop: top is blog (3)
Tip: Real solutions often combine two structures – a map plus a heap, a set plus a queue. Ask what each part of the problem needs to do quickly.
Remember: Java 8 collections never take primitives:
ArrayList<Integer>, not<int>. For huge amounts of numbers, a plainint[]is faster and smaller.