The Java Collections Framework provides a unified architecture for representing and manipulating collections. The core interfaces form a hierarchy:
Key Interfaces:
Iterable
: The root interface extended by all collection interfacesCollection
: Root interface for all collections (except Map)List
: Ordered collection with duplicates allowedSet
: Collection without duplicatesQueue
: Collection designed for holding elements prior to processingMap
: Stores key-value pairs (not part of Collection hierarchy but part of Collections Framework)Iterable └── Collection ├── List ├── Set │ └── SortedSet └── Queue └── Deque Map └── SortedMap
The List
interface represents an ordered collection (sequence). Elements can be accessed by their index.
Key Implementations:
ArrayList
: Resizable array implementation. Fast random access.LinkedList
: Doubly-linked list implementation. Fast insertions/deletions.import java.util.ArrayList; import java.util.List; public class ArrayListDemo { public static void main(String[] args) { // Create an ArrayList List<String> fruits = new ArrayList<>(); // Add elements fruits.add("Apple"); fruits.add("Banana"); fruits.add("Orange"); fruits.add(1, "Mango"); // Insert at index 1 System.out.println("ArrayList: " + fruits); System.out.println("Element at index 2: " + fruits.get(2)); // Remove element fruits.remove("Banana"); System.out.println("After removal: " + fruits); // Check size System.out.println("Size: " + fruits.size()); } }
ArrayList: [Apple, Mango, Banana, Orange] Element at index 2: Banana After removal: [Apple, Mango, Orange] Size: 3
import java.util.LinkedList; import java.util.List; public class LinkedListDemo { public static void main(String[] args) { // Create a LinkedList List<Integer> numbers = new LinkedList<>(); // Add elements numbers.add(10); numbers.add(20); numbers.add(30); numbers.addFirst(5); // Add to beginning numbers.addLast(40); // Add to end System.out.println("LinkedList: " + numbers); // Remove first and last numbers.removeFirst(); numbers.removeLast(); System.out.println("After removal: " + numbers); System.out.println("First element: " + numbers.get(0)); } }
LinkedList: [5, 10, 20, 30, 40] After removal: [10, 20, 30] First element: 10
The Set
interface represents a collection that contains no duplicate elements.
Key Implementations:
HashSet
: Backed by a hash table. No ordering guarantees.LinkedHashSet
: Maintains insertion order.TreeSet
: Elements are sorted in natural order.import java.util.HashSet; import java.util.Set; public class HashSetDemo { public static void main(String[] args) { Set<String> cities = new HashSet<>(); cities.add("London"); cities.add("Paris"); cities.add("New York"); cities.add("London"); // Duplicate System.out.println("HashSet: " + cities); System.out.println("Contains 'Paris'? " + cities.contains("Paris")); cities.remove("New York"); System.out.println("After removal: " + cities); } }
HashSet: [New York, London, Paris] Contains 'Paris'? true After removal: [London, Paris]
import java.util.Set; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { Set<Integer> numbers = new TreeSet<>(); numbers.add(50); numbers.add(20); numbers.add(80); numbers.add(10); numbers.add(20); // Duplicate System.out.println("TreeSet (Sorted): " + numbers); System.out.println("First element: " + ((TreeSet<Integer>) numbers).first()); System.out.println("Last element: " + ((TreeSet<Integer>) numbers).last()); } }
TreeSet (Sorted): [10, 20, 50, 80] First element: 10 Last element: 80
The Map
interface represents an object that maps keys to values. A map cannot contain duplicate keys.
Key Implementations:
HashMap
: Hash table implementation. No ordering guarantees.LinkedHashMap
: Maintains insertion order of keys.TreeMap
: Keys are sorted in natural order.import java.util.HashMap; import java.util.Map; public class HashMapDemo { public static void main(String[] args) { Map<String, Integer> ageMap = new HashMap<>(); ageMap.put("Alice", 30); ageMap.put("Bob", 25); ageMap.put("Charlie", 35); ageMap.put("Alice", 31); // Update existing System.out.println("HashMap: " + ageMap); System.out.println("Alice's age: " + ageMap.get("Alice")); ageMap.remove("Bob"); System.out.println("After removal: " + ageMap); } }
HashMap: {Alice=31, Bob=25, Charlie=35} Alice's age: 31 After removal: {Alice=31, Charlie=35}
import java.util.Map; import java.util.TreeMap; public class TreeMapDemo { public static void main(String[] args) { Map<String, Double> productPrices = new TreeMap<>(); productPrices.put("Laptop", 999.99); productPrices.put("Monitor", 249.99); productPrices.put("Keyboard", 49.99); productPrices.put("Mouse", 25.99); System.out.println("TreeMap (Sorted by key): " + productPrices); System.out.println("First product: " + ((TreeMap<String, Double>) productPrices).firstKey()); System.out.println("Last product: " + ((TreeMap<String, Double>) productPrices).lastKey()); } }
TreeMap (Sorted by key): {Keyboard=49.99, Laptop=999.99, Monitor=249.99, Mouse=25.99} First product: Keyboard Last product: Mouse
The Queue
interface represents a collection designed for holding elements prior to processing, typically in a FIFO manner.
Key Implementations:
PriorityQueue
: Elements processed based on priorityArrayDeque
: Resizable array implementation of DequeLinkedList
: Also implements Deque interfaceimport java.util.PriorityQueue; import java.util.Queue; public class PriorityQueueDemo { public static void main(String[] args) { Queue<Integer> priorityQueue = new PriorityQueue<>(); priorityQueue.add(30); priorityQueue.add(10); priorityQueue.add(20); priorityQueue.add(5); System.out.println("PriorityQueue: " + priorityQueue); // Process elements while (!priorityQueue.isEmpty()) { System.out.println("Processing: " + priorityQueue.poll()); } } }
PriorityQueue: [5, 10, 20, 30] Processing: 5 Processing: 10 Processing: 20 Processing: 30
Iterators provide a way to traverse collections safely and remove elements during iteration.
Key Differences:
Iterator
: Can traverse only forward and remove elementsListIterator
: Can traverse both forward and backward, and can add/set elementsimport java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorDemo { public static void main(String[] args) { List<String> colors = new ArrayList<>(); colors.add("Red"); colors.add("Green"); colors.add("Blue"); colors.add("Yellow"); Iterator<String> iterator = colors.iterator(); System.out.println("Iterating forward:"); while (iterator.hasNext()) { String color = iterator.next(); System.out.println(color); // Remove Blue if (color.equals("Blue")) { iterator.remove(); } } System.out.println("\nAfter removal: " + colors); } }
Iterating forward: Red Green Blue Yellow After removal: [Red, Green, Yellow]
Both interfaces are used for sorting objects, but they differ in implementation:
Feature | Comparable | Comparator |
---|---|---|
Interface | java.lang.Comparable |
java.util.Comparator |
Method | compareTo(T o) |
compare(T o1, T o2) |
Sorting Logic | Natural ordering (defined in the class) | Custom ordering (defined externally) |
Modification | Modifies the original class | Doesn't modify the original class |
Usage | Collections.sort(list) |
Collections.sort(list, comparator) |
public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Student other) { return this.name.compareTo(other.name); } @Override public String toString() { return name + " (" + age + ")"; } }
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ComparableDemo { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("John", 20)); students.add(new Student("Alice", 22)); students.add(new Student("Bob", 19)); Collections.sort(students); System.out.println("Students sorted by name:"); students.forEach(System.out::println); } }
Students sorted by name: Alice (22) Bob (19) John (20)