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 interface
import 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 elements
import 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)