The Java Collections Framework (JCF) is a set of classes and interfaces that implement commonly reusable data structures.
It provides a unified architecture for storing and manipulating groups of objects. Before the JCF, Java had several ad-hoc classes like Array, Vector, and Hashtable, but they didn't share a common interface, making them difficult to use together. The JCF fixed this by providing a standardized set of tools.
The framework is built around a set of core interfaces. The main ones are:
!Collections Framework Diagram
Collection Interface: The root of the hierarchy. It represents a group of objects, known as its elements. It defines basic methods like add(), remove(), size(), and iterator().
Set Interface: Extends Collection. A collection that cannot contain duplicate elements. Think of a mathematical set.HashSet, TreeSet, LinkedHashSet.List Interface: Extends Collection. An ordered collection (also known as a sequence). Lists can contain duplicate elements. You can access elements by their integer index.ArrayList, LinkedList.Queue Interface: Extends Collection. A collection used to hold elements prior to processing. Besides basic Collection operations, queues provide additional insertion, extraction, and inspection operations. Typically, queues order elements in a FIFO (first-in-first-out) manner.LinkedList, PriorityQueue.Map Interface: This interface is not a true Collection because it doesn't extend the Collection interface, but it's a core part of the framework. It maps unique keys to values.
HashMap, TreeMap, LinkedHashMap.Here's a quick look at the most frequently used collection classes:
| Interface | Implementation | Description |
|---|---|---|
List |
ArrayList |
A resizable array. Fast for random access (get()), but slower for insertions and deletions in the middle. |
List |
LinkedList |
A doubly-linked list. Fast for insertions and deletions, but slower for random access. |
Set |
HashSet |
Stores elements in a hash table. Provides the best performance on average (O(1)), but makes no guarantees about iteration order. |
Set |
TreeSet |
Stores elements in a sorted tree structure. Elements are ordered, but performance is slower (O(log n)). |
Set |
LinkedHashSet |
A hash table and linked list implementation. Provides insertion-ordered iteration and fast (O(1)) performance. |
Map |
HashMap |
A hash table implementation of the Map interface. Provides O(1) performance for get() and put(). No order is guaranteed. |
Map |
TreeMap |
A tree-based implementation. Keys are sorted, but performance is O(log n). |
Map |
LinkedHashMap |
A hash table and linked list implementation. Provides insertion-ordered iteration and fast (O(1)) performance. |
In the next chapters, we will explore each of these interfaces and implementations in detail.
Historically, creating and initializing a collection with values required several lines of code. Since Java 9, the framework includes convenient static factory methods like List.of(), Set.of(), and Map.of() to create collections quickly in a single line.
It is crucial to note that collections created this way are immutable (unmodifiable). If you try to add, remove, or modify elements after creation, the program will crash with an UnsupportedOperationException.
import java.util.List; import java.util.Map; import java.util.Set;public class Main { public static void main(String[] args) { // Create an immutable List List<String> colors = List.of("Red", "Green", "Blue"); // colors.add("Yellow"); // This would throw an exception! // Create an immutable Set Set<Integer> primeNumbers = Set.of(2, 3, 5, 7, 11); // Create an immutable Map (Key1, Value1, Key2, Value2, ...) Map<String, String> capitals = Map.of( "USA", "Washington D.C.", "France", "Paris", "Japan", "Tokyo" ); System.out.println("Colors: " + colors); System.out.println("Primes: " + primeNumbers); System.out.println("Capitals Map: " + capitals); } }
When you use collections that maintain a sorted order (like TreeSet or TreeMap), or when you use sorting algorithms on a List, Java needs to know how to compare the objects. For built-in types like String or Integer, Java already knows. But for your custom classes, you must define the sorting rules.
The most common way to do this is by having your custom class implement the Comparable interface and overriding the compareTo() method to define its "natural" default sorting order.
import java.util.ArrayList; import java.util.Collections; import java.util.List;// Implement Comparable and specify the type to compare against class Student implements Comparable<Student> { String name; int grade;
public Student(String name, int grade) { this.name = name; this.grade = grade; }
@Override public int compareTo(Student otherStudent) { // Sort by grade in descending order (highest first) return Integer.compare(otherStudent.grade, this.grade); }
@Override public String toString() { return name + " (" + grade + ")"; } }
public class Main { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("Alice", 85)); students.add(new Student("Bob", 92)); students.add(new Student("Charlie", 78)); // Collections.sort automatically uses the compareTo method we wrote! Collections.sort(students); System.out.println(students); // Outputs: [Bob (92), Alice (85), Charlie (78)] } }
Which interface maps unique keys to values and is NOT a true Collection?