Collections Overview
IntermediateNavigate the entire Java Collections Framework — the hierarchy, core interfaces, implementations, and how to choose the right collection for the job.
Overview
The Java Collections Framework (JCF) is a unified architecture for representing and manipulating groups of objects. At its root is Iterable, then Collection, which branches into List (ordered, duplicates allowed), Set (no duplicates), and Queue (FIFO/priority ordering). Map is separate — it stores key-value pairs. Every collection interface has multiple implementations with different performance trade-offs. Knowing which implementation to pick and why is one of the most-tested Java interview topics.
The Hierarchy: Iterable → Collection → List/Set/Queue
Iterable<E> — root; defines iterator(), enabling enhanced for-each Collection<E> — extends Iterable; adds add(), remove(), size(), contains(), isEmpty(), toArray()
List<E> — ordered, index-based, duplicates allowed ArrayList — dynamic array; O(1) random access; best default LinkedList — doubly-linked; O(1) head/tail insert; implements Deque too CopyOnWriteArrayList — thread-safe; snapshot on write
Set<E> — no duplicates; equals/hashCode determine membership HashSet — O(1) ops; no order LinkedHashSet — insertion order TreeSet — sorted order; O(log n) ops
Queue<E> / Deque<E> — FIFO or double-ended ArrayDeque — resizable array; best Stack and Queue implementation PriorityQueue — min-heap; O(log n) poll LinkedList — implements Deque too
import java.util.*;
public class CollectionHierarchy {
public static void main(String[] args) {
// List — ordered, index-based
List<String> list = new ArrayList<>(List.of("banana", "apple", "cherry"));
list.add("date");
Collections.sort(list);
System.out.println(list); // [apple, banana, cherry, date]
// Set — no duplicates
Set<String> set = new HashSet<>(list);
set.add("apple"); // duplicate — silently ignored
System.out.println(set.size()); // 4
// Queue — FIFO
Queue<String> queue = new ArrayDeque<>(List.of("first", "second", "third"));
System.out.println(queue.poll()); // first
System.out.println(queue.peek()); // second (doesn't remove)
// All are Collections — polymorphic utility methods work on all
System.out.println(Collections.frequency(list, "apple")); // 1
Collections.shuffle(list);
// Iterable — enhanced for-each works on all
for (String s : set) System.out.print(s + " ");
System.out.println();
// Convert between collections
List<String> fromSet = new ArrayList<>(set);
Set<String> fromList = new LinkedHashSet<>(list); // preserves order, dedupes
}
}Map — Key-Value Storage
Map<K,V> is not a Collection — it does not extend Collection or Iterable. It stores key-value pairs where each key is unique.
HashMap — O(1) average get/put; no order; allows one null key LinkedHashMap — insertion order; slightly slower than HashMap TreeMap — sorted by key; O(log n); no null keys ConcurrentHashMap — thread-safe; O(1) average; no null keys or values EnumMap — array-backed by ordinal; fastest for enum keys
Iterate via entrySet() (key+value), keySet() (keys only), or values() (values only).
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
// HashMap — most common, O(1) average
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 82);
scores.put("Carol", 91);
System.out.println(scores.get("Alice")); // 95
System.out.println(scores.getOrDefault("Dave", 0)); // 0
scores.putIfAbsent("Bob", 100); // not replaced
System.out.println(scores.get("Bob")); // 82
// Iterate entrySet
for (Map.Entry<String, Integer> e : scores.entrySet()) {
System.out.println(e.getKey() + " → " + e.getValue());
}
// Compute patterns
Map<String, List<String>> groups = new HashMap<>();
String[] words = {"apple", "ant", "banana", "bear", "cherry"};
for (String w : words) {
groups.computeIfAbsent(String.valueOf(w.charAt(0)), k -> new ArrayList<>())
.add(w);
}
System.out.println(groups);
// {a=[apple, ant], b=[banana, bear], c=[cherry]}
// merge — combine existing + new value
scores.merge("Alice", 5, Integer::sum); // Alice: 95 + 5 = 100
System.out.println(scores.get("Alice")); // 100
// TreeMap — sorted keys
TreeMap<String, Integer> sorted = new TreeMap<>(scores);
System.out.println(sorted.firstKey()); // Alice
System.out.println(sorted.lastKey()); // Carol
}
}Choosing the Right Collection
Quick decision guide:
Need a simple ordered list with fast index access? → ArrayList Need fast inserts/deletes at both ends? → ArrayDeque Need unique elements, don't care about order? → HashSet Need unique elements, insertion order? → LinkedHashSet Need unique elements, sorted? → TreeSet Need key-value lookup, don't care about order? → HashMap Need key-value lookup, sorted keys? → TreeMap Need a min or max heap? → PriorityQueue Need thread-safe map? → ConcurrentHashMap Need immutable collections? → List.of(), Set.of(), Map.of() (Java 9+)
import java.util.*;
public class CollectionChoice {
public static void main(String[] args) {
// Immutable factory methods (Java 9+)
List<String> immList = List.of("a", "b", "c");
Set<String> immSet = Set.of("x", "y", "z");
Map<String, Integer> immMap = Map.of("one", 1, "two", 2);
// immList.add("d"); // UnsupportedOperationException
// Defensive copy when you need a mutable version
List<String> mutable = new ArrayList<>(immList);
mutable.add("d");
// Collections utility methods
List<Integer> nums = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9));
System.out.println(Collections.max(nums)); // 9
System.out.println(Collections.min(nums)); // 1
System.out.println(Collections.frequency(nums, 1)); // 2
Collections.sort(nums);
System.out.println(Collections.binarySearch(nums, 5)); // index of 5
Collections.reverse(nums);
System.out.println(nums); // [9, 5, 4, 3, 1, 1]
// Unmodifiable wrapper — read-only view of mutable collection
List<Integer> readOnly = Collections.unmodifiableList(nums);
// readOnly.add(0); // UnsupportedOperationException
}
}Interactive Visualization
Key Points to Remember
- Collection hierarchy: Iterable → Collection → List/Set/Queue; Map is separate
- ArrayList is the best default List; ArrayDeque is the best Stack and Queue
- HashSet/HashMap O(1) average; TreeSet/TreeMap O(log n) sorted; LinkedHashSet/LinkedHashMap insertion order
- Map.Entry gives both key and value in entrySet() iteration
- computeIfAbsent(), merge(), putIfAbsent() are essential modern Map patterns
- List.of(), Set.of(), Map.of() (Java 9+) create compact, immutable collections
Practice Collections Overview in the Playground
Run and modify code directly in your browser - no setup needed.
Interview Questions
Sign in to ask AriaWhat is the difference between Collection and Collections in Java?
When would you use LinkedList over ArrayList?
What is the difference between HashMap, LinkedHashMap, and TreeMap?
How does HashSet ensure no duplicate elements?
What is the difference between fail-fast and fail-safe iterators?
Ask Aria about Collections Overview
Your personal AI tutor — ask anything about this concept