Collections Framework: Overview
The Java Collections Framework (JCF) is a set of interfaces, classes, and algorithms in the java.util package that provide ready-made ways to store, retrieve, and manipulate groups of objects.
In simple words:
Collections = Ready-made data structures (list, set, queue, map) with common methods
Real-Life Example: Containers
Different situations need different containers:
1Shopping list → order matters, duplicates allowed → List2Unique ID cards → no duplicates → Set3Queue at a ticket counter → first in, first out → Queue4Phone contacts → name → number (key-value) → MapJava gives a ready-made container for each need, so you do not have to build them yourself.
Why Collections? (Problems with Arrays)
| Feature | Array | Collection |
|---|---|---|
| Size | Fixed | Dynamic (grows and shrinks) |
| Data type | Primitives and objects | Objects only (use wrapper classes) |
| Ready methods | Very few | Many (add, remove, contains, ...) |
| Data structures | Only an indexed sequence | List, Set, Queue, Map, etc. |
| Type safety | Checked at compile time | Checked with Generics |
Collection Hierarchy
Points to notice:
| Point | Explanation |
|---|---|
Collection extends Iterable | So every collection can be used in a for-each loop |
Map does not extend Collection | It stores key-value pairs, not single elements |
LinkedList implements List and Deque | It can behave as a list and as a queue |
Collection is an interface | Collections (with an "s") is a utility class |
The Iterable Interface (Top of the Hierarchy)
Iterable is the root. Any class that implements it can be used in the for-each loop.
| Method | Purpose |
|---|---|
iterator() | Returns an Iterator to traverse elements |
forEach() | Performs an action on each element (Java 8+) |
The Collection Interface: Common Methods
These methods are available in every List, Set, and Queue.
| Method | Purpose |
|---|---|
boolean add(E e) | Adds an element |
boolean addAll(Collection c) | Adds all elements of another collection |
boolean remove(Object o) | Removes one occurrence of the element |
boolean removeAll(Collection c) | Removes all elements that are present in c |
boolean retainAll(Collection c) | Keeps only elements that are present in c |
boolean removeIf(Predicate p) | Removes elements matching a condition (Java 8+) |
boolean contains(Object o) | Checks if the element exists |
boolean containsAll(Collection c) | Checks if all elements of c exist |
int size() | Returns the number of elements |
boolean isEmpty() | Checks if the collection is empty |
void clear() | Removes all elements |
Iterator<E> iterator() | Returns an iterator |
Object[] toArray() | Converts the collection to an array |
Stream<E> stream() | Returns a stream for processing (Java 8+) |
Methods That Are NOT in Collection
Each sub-interface adds its own methods.
| Interface | Extra methods |
|---|---|
| List | get(i), set(i, e), add(i, e), remove(i), indexOf(), subList(), sort() |
| Set | No new methods (only adds the "no duplicates" rule) |
| SortedSet / NavigableSet | first(), last(), headSet(), tailSet(), floor(), ceiling() |
| Queue | offer(), poll(), peek(), element(), remove() |
| Deque | addFirst(), addLast(), pollFirst(), pollLast(), push(), pop() |
| Map | put(), get(), containsKey(), keySet(), values(), entrySet() |
The Map Interface (Separate Hierarchy)
Map stores key-value pairs. Keys are unique, values can repeat.
import java.util.*;public class Main {public static void main(String[] args) {Map<Integer, String> students = new HashMap<>();students.put(1, "Ravi");students.put(2, "Anita");students.put(1, "Kiran"); // same key: old value is replacedSystem.out.println(students); // {1=Kiran, 2=Anita}System.out.println(students.get(2)); // AnitaSystem.out.println(students.containsKey(1)); // trueSystem.out.println(students.keySet()); // [1, 2]System.out.println(students.values()); // [Kiran, Anita]}}
Since Map is not a Collection, you can get a collection view of it using keySet(), values(), or entrySet().
Iterating Over Collections
1. For-each Loop
for (String fruit : fruits) {System.out.println(fruit);}
2. Iterator
Iterator<String> it = fruits.iterator();while (it.hasNext()) {String fruit = it.next();System.out.println(fruit);}
3. forEach with Lambda (Java 8+)
fruits.forEach(fruit -> System.out.println(fruit));fruits.forEach(System.out::println); // method reference
Safe Removal While Iterating
Removing from a collection inside a for-each loop throws ConcurrentModificationException (this is called fail-fast behavior).
// Wrongfor (String f : fruits) {if (f.equals("Apple")) {fruits.remove(f); // ConcurrentModificationException}}// Correct: Iterator.remove()Iterator<String> it = fruits.iterator();while (it.hasNext()) {if (it.next().equals("Apple")) {it.remove();}}// Correct: removeIf()fruits.removeIf(f -> f.equals("Apple"));
Generics in Collections
Generics make collections type safe, so the compiler catches wrong types and no casting is needed.
// Without generics (old style): riskyList list = new ArrayList();list.add("Hello");list.add(100);String s = (String) list.get(1); // ClassCastException at runtime// With generics: safeList<String> names = new ArrayList<>();names.add("Hello");// names.add(100); // Compile-time error
Collections store objects only, so primitives use wrapper classes:
| Primitive | Wrapper |
|---|---|
int | Integer |
double | Double |
char | Character |
boolean | Boolean |
1List<int> Not allowed2List<Integer> CorrectOrdering Terms Explained
| Term | Meaning | Example |
|---|---|---|
| Ordered | Elements stay in the order they were added (insertion order) | ArrayList, LinkedHashSet |
| Unordered | No guarantee about the order | HashSet, HashMap |
| Sorted | Elements are arranged by a sorting rule | TreeSet, TreeMap |
"Ordered" and "sorted" are not the same. Ordered means insertion order. Sorted means arranged by value.
The Collections Utility Class
Collections (with an "s") is a class with static helper methods. It is different from the Collection interface.
| Collection (interface) | Collections (utility class) |
|---|---|
| Root interface of the hierarchy | Class with static utility methods |
Defines add(), remove(), etc. | Provides sort(), reverse(), max(), etc. |
List<Integer> nums = new ArrayList<>(List.of(30, 10, 20));Collections.sort(nums); // [10, 20, 30]Collections.reverse(nums); // [30, 20, 10]Collections.shuffle(nums); // random orderSystem.out.println(Collections.max(nums)); // 30System.out.println(Collections.min(nums)); // 10System.out.println(Collections.frequency(nums, 10)); // 1List<Integer> fixed = Collections.unmodifiableList(nums); // read-only view
Sorting: Comparable vs Comparator (Preview)
| Feature | Comparable | Comparator |
|---|---|---|
| Package | java.lang | java.util |
| Method | compareTo(T o) | compare(T a, T b) |
| Sorting logic | Inside the class (natural order) | Outside the class (custom order) |
| Sorting orders | Only one | Many |
TreeSet, TreeMap, and PriorityQueue use these to decide the order. We will cover them in detail later.
Legacy Classes (Avoid in New Code)
| Legacy class | Modern replacement |
|---|---|
Vector | ArrayList (or CopyOnWriteArrayList for thread safety) |
Stack | ArrayDeque |
Hashtable | HashMap (or ConcurrentHashMap for thread safety) |
Thread Safety (Preview)
Most collections (ArrayList, HashSet, HashMap) are not thread-safe. For multi-threaded programs, use:
| Option | Example |
|---|---|
| Synchronized wrappers | Collections.synchronizedList(list) |
Concurrent collections (java.util.concurrent) | ConcurrentHashMap, CopyOnWriteArrayList |
How to Choose a Collection
1Need key-value pairs? → Map2 Need sorted keys? → TreeMap3 Need insertion order? → LinkedHashMap4 Just fast lookup? → HashMap5 6Need unique elements? → Set7 Need sorted? → TreeSet8 Need insertion order? → LinkedHashSet9 Just fast lookup? → HashSet10 11Need duplicates and index access? → List12 Mostly reading by index? → ArrayList13 Frequent insert/delete at the ends? → LinkedList / ArrayDeque14 15Need FIFO / LIFO processing? → Queue / Deque (ArrayDeque)16Need highest/lowest priority first? → PriorityQueueKey Benefits
| Benefit | Explanation |
|---|---|
| Reusability | Ready-made data structures, no need to write your own |
| Performance | Well-tested, efficient implementations |
| Consistency | Common methods across all collections |
| Flexibility | Switch implementation easily (ArrayList → LinkedList) |
| Type safety | Generics catch errors at compile time |
Programming to an Interface
A good habit is to declare the variable using the interface type, so you can change the implementation later without changing the rest of the code.
List<String> names = new ArrayList<>(); // ✅ interface on the left// later: names = new LinkedList<>(); // only one line changesArrayList<String> names2 = new ArrayList<>(); // ❌ tied to ArrayList
Interview Definition
The Java Collections Framework is a unified architecture of interfaces, implementation classes, and algorithms in the
java.utilpackage for storing and manipulating groups of objects, withCollectionandMapas its two root interfaces.
Remember
Collection → List, Set, Queue (common methods live here). Map is separate and stores key-value pairs.
Collectionsis only a utility class.