Lesson 13 โข Expert
Collections Framework
Master Java's powerful data structure library โ the right collection choice can make your program 100x faster.
๐ Before You Start
You should understand:
- Arrays (Lesson 7) โ fixed-size data storage
- OOP (Lesson 9) โ classes, objects, and interfaces
- Loops (Lesson 5) โ iterating through data
What You'll Learn
- โ ArrayList โ dynamic resizable arrays for ordered data
- โ HashMap โ key-value pairs for blazing-fast lookups
- โ HashSet โ unique elements with O(1) contains checks
- โ LinkedList, Stack, and Queue for specialized needs
- โ Iterating with for-each, iterators, and streams
- โ Choosing the right collection (performance guide)
1๏ธโฃ Why Collections Matter
Real-world analogy: Collections are like different types of storage containers. An ArrayList is a numbered filing cabinet โ great for ordered access. A HashMap is a dictionary โ look up any word instantly. A HashSet is a bag of unique marbles โ quickly check "is this marble in the bag?"
Why not just use arrays? Arrays have a fixed size. Collections resize dynamically, offer rich APIs (search, sort, filter), and provide type safety with generics.
2๏ธโฃ ArrayList โ Your Go-To List
Use ArrayList when you need ordered data with fast index access. It's the most commonly used collection.
List<String> names = new ArrayList<>();
names.add("Alice"); // add to end
names.add("Bob");
names.add(1, "Charlie"); // insert at index 1
names.get(0); // "Alice" โ O(1)
names.set(0, "Alicia"); // replace at index
names.remove("Bob"); // remove by value
names.size(); // current count
names.contains("Charlie"); // true
// Sort and iterate
Collections.sort(names); // alphabetical
for (String name : names) { // for-each
System.out.println(name);
}Performance: O(1) for get/set by index, O(n) for insert/remove in the middle.
Try It: ArrayList Operations
Practice adding, removing, sorting, and searching in lists
// ๐ก Try modifying this code and see what happens!
// ArrayList Operations (Simulated)
console.log("=== ArrayList Operations ===\n");
// 1. Basic operations
let names = ["Alice", "Bob", "Charlie"];
console.log("1. Initial list:", names.join(", "));
names.push("Diana");
console.log(" After add('Diana'):", names.join(", "));
names.splice(1, 0, "Eve"); // insert at index 1
console.log(" After insert(1, 'Eve'):", names.join(", "));
console.log(" get(0):", names[0]);
console.log(" size:"
...3๏ธโฃ HashMap โ Key-Value Lookups
Analogy: Like a phone book โ you look up a person's name (key) to find their number (value). You don't search page by page; you jump directly to the right entry.
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 87);
scores.get("Alice"); // 95 โ O(1) average!
scores.containsKey("Bob"); // true
scores.getOrDefault("Diana", 0); // 0 (safe default)
// Common pattern: counting frequency
Map<String, Integer> freq = new HashMap<>();
for (String word : words) {
freq.put(word, freq.getOrDefault(word, 0) + 1);
}4๏ธโฃ HashSet โ Unique Elements
Use HashSet when you need to track unique items. Duplicates are silently ignored.
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("oop");
tags.add("java"); // duplicate โ silently ignored!
tags.size(); // 2
tags.contains("java"); // true โ O(1)!
// Great for deduplication
List<String> withDupes = Arrays.asList("a", "b", "a", "c", "b");
Set<String> unique = new HashSet<>(withDupes); // {"a", "b", "c"}Try It: HashMap & HashSet
Build a word frequency counter and deduplication system
// ๐ก Try modifying this code and see what happens!
// HashMap & HashSet (Simulated)
console.log("=== HashMap & HashSet ===\n");
// 1. HashMap โ scores
console.log("1. HashMap (Student Scores):");
let scores = new Map();
scores.set("Alice", 95);
scores.set("Bob", 87);
scores.set("Charlie", 92);
scores.set("Diana", 88);
console.log(" Alice:", scores.get("Alice"));
console.log(" Size:", scores.size);
console.log(" Has 'Bob':", scores.has("Bob"));
console.log(" Unknown:", scores.get("Unkno
...5๏ธโฃ Which Collection Should I Use?
| Need | Use | Why |
|---|---|---|
| Ordered list, read by index | ArrayList | O(1) get, auto-resize |
| Frequent insert/remove at ends | LinkedList | O(1) add/remove at head/tail |
| Key โ value mapping | HashMap | O(1) lookup by key |
| Sorted key โ value | TreeMap | Keys always sorted |
| Unique elements only | HashSet | O(1) contains check |
| LIFO (undo, backtracking) | Deque/Stack | push/pop O(1) |
| FIFO (task queue, BFS) | Queue/LinkedList | offer/poll O(1) |
Default choice: Start with ArrayList for lists and HashMap for key-value pairs.
6๏ธโฃ Common Beginner Mistakes
โ Mistake 1: Modifying a collection while iterating
// CRASHES with ConcurrentModificationException!
for (String s : list) {
if (s.equals("remove")) list.remove(s);
}
// CORRECT: use removeIf (Java 8+)
list.removeIf(s -> s.equals("remove"));โ Mistake 2: Using raw types (no generics)
List list = new ArrayList(); // BAD โ no type safety List<String> list = new ArrayList<>(); // GOOD
โ Mistake 3: Not overriding hashCode() with HashMap keys
If you override equals(), you must also override hashCode().
Try It: Stack, Queue & Practical Patterns
Use Stack for undo history and Queue for task processing
// ๐ก Try modifying this code and see what happens!
// Stack, Queue & Practical Patterns (Simulated)
console.log("=== Stack & Queue ===\n");
// 1. Stack (LIFO โ Last In, First Out)
console.log("1. Browser History Stack:");
let history = [];
history.push("google.com");
history.push("github.com");
history.push("stackoverflow.com");
console.log(" History:", [...history].join(" โ "));
console.log(" Current page:", history[history.length - 1]);
console.log(" Back (pop):", history.pop());
conso
...๐ Quick Reference
| Collection | Key Methods | Complexity |
|---|---|---|
| ArrayList | add, get, set, remove, size | O(1) get, O(n) insert |
| LinkedList | addFirst, addLast, poll | O(1) ends, O(n) middle |
| HashMap | put, get, containsKey, remove | O(1) average |
| TreeMap | put, get, firstKey, lastKey | O(log n) sorted |
| HashSet | add, contains, remove | O(1) average |
| Stack/Deque | push, pop, peek | O(1) |
๐ Lesson Complete!
You now know how to use Java's core collections โ ArrayList, HashMap, HashSet, Stack, and Queue โ and how to choose the right one based on your data access patterns.
Next up: Generics โ write type-safe, reusable code that works with any data type.
Sign up for free to track which lessons you've completed and get learning reminders.