Java Collections Framework - Complete Tutorial
Master Java Collections: Learn List, Set, Map, Queue interfaces with ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, PriorityQueue implementations, iterators, comparators and best practices.
1. Introduction to Collections Framework
The Java Collections Framework provides interfaces and classes for storing and manipulating groups of objects as units.
- Root interfaces: Collection, Map
- Legacy Vector and Hashtable exist
- Generics add compile-time type safety
- Algorithm utilities in Collections class
import java.util.*;
public class CollIntro {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
System.out.println(list);
}
}
2. List Interface
List stores ordered elements with duplicates allowed. ArrayList gives fast random access; LinkedList gives fast inserts at ends.
- ArrayList — dynamic array backing
- LinkedList — doubly linked nodes
- List allows duplicate elements
- Indexed access with get(i)
import java.util.*;
public class ListDemo {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(10);
nums.add(20);
System.out.println(nums.get(0));
}
}
3. Set Interface
Set stores unique elements with no duplicates. HashSet offers O(1) average operations; TreeSet keeps sorted order.
- HashSet — hash table, no order
- TreeSet — red-black tree, sorted
- LinkedHashSet — insertion order
- add returns false if duplicate
import java.util.*;
public class SetDemo {
public static void main(String[] args) {
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("java");
System.out.println(tags.size());
}
}
4. Map Interface
Map stores key-value pairs with unique keys. HashMap is the general-purpose implementation; TreeMap sorts by keys.
- Keys must be unique
- One value per key
- HashMap allows one null key
- Map does not extend Collection
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 88);
System.out.println(scores.get("Alice"));
}
}
5. Queue Interface
Queue models FIFO (first-in-first-out) processing. PriorityQueue orders elements by priority or natural ordering.
- LinkedList implements Queue
- PriorityQueue — heap-based priority
- Deque supports operations at both ends
- Useful for BFS and task scheduling
import java.util.*;
public class QueueDemo {
public static void main(String[] args) {
Queue<String> q = new LinkedList<>();
q.offer("first");
q.offer("second");
System.out.println(q.poll());
}
}
6. Iterators and Comparators
Iterator traverses collections safely. Comparator defines custom sort order separate from natural ordering via Comparable.
- iterator.hasNext() and next()
- remove() during iteration with Iterator
- Comparator.comparing for lambdas
- Comparable compareTo for natural order
import java.util.*;
public class IteratorDemo {
public static void main(String[] args) {
List<String> names = Arrays.asList("Bob", "Ana", "Cal");
Collections.sort(names, Comparator.comparing(String::length));
System.out.println(names);
}
}
7. Performance Comparison
Choose implementations based on access patterns. ArrayList wins for indexed reads; HashSet and HashMap win for average lookups.
- ArrayList get: O(1), add end: O(1) amortized
- LinkedList add/remove at ends: O(1)
- HashMap get/put: O(1) average
- TreeSet/TreeMap: O(log n) sorted ops
8. Practical Collection Examples
Collections appear in every Java application: caching, grouping, deduplication, and sorting query results.
- Remove duplicates with HashSet
- Frequency count with HashMap
- Sort students by grade
- Stack behavior with ArrayDeque
import java.util.*;
public class FreqDemo {
public static void main(String[] args) {
String[] words = {"a", "b", "a", "c", "a"};
Map<String, Integer> freq = new HashMap<>();
for (String w : words) {
freq.put(w, freq.getOrDefault(w, 0) + 1);
}
System.out.println(freq);
}
}
9. Collections Best Practices
Program to interfaces, choose the right implementation, and use generics for type safety.
- Declare as List, Set, Map interface types
- Pick implementation for access pattern
- Use immutable collections when possible
- Avoid raw types
- Prefer isEmpty() over size() == 0