Java Collections β List, Set, Map, Queue and the Java Collections Framework
The Java Collections Framework is a unified API for storing and manipulating groups of objects. The four pillars are List (ordered, indexed), Set (no duplicates), Map (key β value) and Queue/Deque (FIFO/LIFO). Each pillar is an interface with multiple implementations that trade off speed, ordering and memory.
Pick the right collection
| Need | Use | Get / put / contains |
|---|---|---|
| Ordered list, frequent indexing | ArrayList | O(1) get / O(1) amortised add |
| Frequent insert/remove at ends | ArrayDeque | O(1) at both ends |
| Unique elements, no order | HashSet | O(1) average |
| Unique elements, sorted | TreeSet | O(log n) |
| Unique elements, insertion order preserved | LinkedHashSet | O(1) average |
| Key β value lookup | HashMap | O(1) average |
| Key β value, sorted by key | TreeMap | O(log n) |
| FIFO queue (single-threaded) | ArrayDeque | O(1) |
| FIFO queue (multi-threaded) | ConcurrentLinkedQueue / LinkedBlockingQueue | O(1) |
Modern factory methods (Java 9+)
List<String> names = List.of("Alice", "Bob"); // immutable
Set<Integer> primes = Set.of(2, 3, 5, 7); // immutable
Map<String,Integer> m = Map.of("a", 1, "b", 2); // immutable, max 10 entries
Map<String,Integer> big = Map.ofEntries(
Map.entry("a", 1),
Map.entry("b", 2),
Map.entry("c", 3)); // for > 10 entries
Factory collections are immutable β calling add throws UnsupportedOperationException. They're also more compact than new ArrayList<>() and friends.
List operations
var list = new ArrayList<String>();
list.add("first");
list.add(0, "zeroth"); // insert at index 0
list.set(1, "FIRST"); // replace
list.remove("FIRST"); // by value
list.remove(0); // by index
list.contains("zeroth"); // O(n) scan
Map operations
var votes = new HashMap<String, Integer>();
votes.put("Alice", 1);
votes.merge("Alice", 1, Integer::sum); // increment-or-create β Java 8+
votes.computeIfAbsent("Bob", k -> 0); // lazy init
for (var e : votes.entrySet()) {
System.out.println(e.getKey() + " = " + e.getValue());
}
Iterating safely
// β ConcurrentModificationException
for (String s : list) if (s.isEmpty()) list.remove(s);
// β
Use Iterator.remove()
var it = list.iterator();
while (it.hasNext()) if (it.next().isEmpty()) it.remove();
// β
Or removeIf β Java 8+
list.removeIf(String::isEmpty);
Streams over collections
List<String> longNames = users.stream()
.filter(u -> u.age() >= 18)
.map(User::name)
.filter(n -> n.length() > 5)
.toList(); // Java 16+ β immutable
Map<String,Long> byCity = users.stream()
.collect(Collectors.groupingBy(User::city, Collectors.counting()));
All sub-topics
ArrayListLinkedListHashMapLinkedHashMapTreeMapHashSetTreeSetArrayDequeIteratorandremoveIf- Streams over collections
Common mistakes
- Using
LinkedListby default βArrayListis faster for almost every workload, including head/tail operations on small lists. - Iterating + removing β throws
ConcurrentModificationException. UseIterator.remove()orremoveIf. - Mutable keys in
HashMapβ if a key'shashCodechanges after insertion, you can't find it again. - Returning a mutable internal list β callers can corrupt your state. Return
List.copyOf(internal)or wrap inCollections.unmodifiableList.
Try it & related tools
The JSON to POJO tool generates classes that work with collections (lists of objects, maps as keys). Run snippets in the Java Online Compiler.