Java Collection Framework – A Complete Guide with Examples

Introduction

Why Collections Came into Picture:
✍️In Java, arrays have a fixed size and lack built-in methods for easy manipulation like adding, removing, or searching elements. To overcome these limitations, the Collection Framework was introduced, providing dynamic data structures with rich utility methods. For a detailed understanding of arrays in Java, you can check Java Arrays Tutorial

The Java Collection Framework (JCF) is a unified architecture for storing and manipulating groups of objects. It provides ready-to-use data structures (like List, Set, Map, Queue) and algorithms (like sorting, searching, iteration).

Instead of writing complex data structures manually, Java developers can use these pre-built and optimized collections.

πŸ‘‰ The framework is part of java.util package and was introduced in Java 2 (JDK 1.2), but has been enhanced with each release up to the latest Java 25.

Why Use Collection Framework?

  • Reduces development effort β†’ ready-to-use data structures.
  • Improves performance β†’ optimized implementations.
  • Increases code quality β†’ reusable, consistent APIs.
  • Type safety with Generics (introduced in Java 5).
  • Concurrent utilities (from Java 5 onwards, updated till Java 25).

Collection Framework Hierarchy

At the top level, we have two main root interfaces:

  1. Collection Interface (java.util.Collection)
    • Extended by List, Set, and Queue.
  2. Map Interface (java.util.Map)
    • A separate hierarchy for key-value pairs.

Hierarchy Overview:

                                          Iterable
                                             |
                               +--------------+-------------------------+
                               |                                        |
                      +-----Collection---------------+                 Map
                    /            |                   |                  |
                   /             |                   |                  |
                List            Set----+            Queue            SortedMap
                /                |      \            |                  |
    +--------+----------+        |       \           |                  |
    |        |          |    SortedSet  HashSet    Deque          NavigableMap
ArrayList Vector LinkedList      |         |
                            NavigableSet LinkedHashSet
                                 |
                              TreeSet

Key Interfaces and Classes

At the heart of the Java Collections Framework are a set of key interfaces β€” Collection, List, Set, Queue, Deque, and Map. These interfaces establish the contracts that different collection classes must follow, providing guidelines for how data can be stored, accessed, and manipulated.

  • List Interface
  • Set Interface
  • Queue Interface
  • Deque Interface
  • Map Interface

1. List Interface

Represents an ordered collection that allows duplicate elements and provides positional access. Lists include dynamic arrays, linked structures, and legacy classes designed for sequential storage.

  • Index-based access.

Popular Implementations:

  • ArrayList
  • LinkedList
  • Vector
  • Stack
  • CopyOnWriteArrayList

βœ… Example:

import java.util.*;

public class ListExample {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.add("Apple"); // allows duplicates

        System.out.println("Fruits List: " + fruits);
    }
}

2. Set Interface

Represents a collection that does not allow duplicate elements. Sets are used to model mathematical sets and may or may not preserve insertion order, depending on the implementation.

Popular Implementations:

  • HashSet
  • LinkedHashSet
  • TreeSet
  • CopyOnWriteArraySet

βœ… Example:

import java.util.*;

public class SetExample {
    public static void main(String[] args) {
        Set<String> names = new HashSet<>();
        names.add("Simone");
        names.add("Jeremy");
        names.add("Simone"); // ignored

        System.out.println("Names: " + names);
    }
}

3. Queue Interface

Represents a collection designed for holding elements prior to processing. Queues typically follow FIFO (First-In-First-Out) order, but priority-based or custom orderings are also possible.

Popular Implementations:

  • LinkedList
  • PriorityQueue
  • ArrayDeque
  • ConcurrentLinkedQueue
  • LinkedBlockingQueue

βœ… Example:

import java.util.*;

public class QueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(10);
        queue.add(20);
        queue.add(30);

        System.out.println("Queue: " + queue);
        System.out.println("Removed: " + queue.poll()); // removes first
        System.out.println("After removal: " + queue);
    }
}

4. Deque Interface

A double-ended queue that supports element insertion and removal at both ends. Deques can function as stacks (LIFO) or queues (FIFO), providing flexible access patterns.

Popular Implementations:

  • ArrayDeque.
  • ConcurrentLinkedDeque
  • LinkedBlockingDeque
  • LinkedList

βœ… Example:

import java.util.*;

public class DequeExample {
    public static void main(String[] args) {
        Deque<String> dq = new ArrayDeque<>();
        dq.addFirst("Start");
        dq.addLast("End");

        System.out.println(dq);
    }
}

5. Map Interface

Represents a collection of key–value pairs, where keys are unique and each key maps to exactly one value. Maps are not true collections but provide a way to store and retrieve data based on unique identifiers.

  • Keys are unique, values can be duplicate.

Popular Implementations:

  • HashMap
  • LinkedHashMap
  • TreeMap
  • Hashtable
  • ConcurrentHashMap (thread-safe)

βœ… Example:

import java.util.*;

public class MapExample {
    public static void main(String[] args) {
        Map<Integer, String> students = new HashMap<>();
        students.put(1, "Alice");
        students.put(2, "Bob");
        students.put(3, "Charlie");

        System.out.println("Students: " + students);
        System.out.println("Student with ID 2: " + students.get(2));
    }
}

6.Utility Class: Collections

The Collections class (part of java.util package) is a utility class that provides static methods to operate on or return collections.

It is different from the Collections Framework itself. The Collections Framework provides data structures (List, Set, Map, etc.), while the Collections class provides algorithms and helper methods to work with those data structures.

Key Features of Collections Class

  1. Algorithms β†’ Sorting, Searching, Shuffling, Reversing, Rotating, etc.
  2. Synchronization Wrappers β†’ Convert non-thread-safe collections into thread-safe ones.
  3. Read-only Wrappers β†’ Create immutable collections.
  4. Utility Methods β†’ Frequency count, finding min/max, filling collections, etc.

Method :

MethodDescriptionExample
sort(List<T> list)Sorts the list in ascending order.Collections.sort(list);
reverse(List<?> list)Reverses the list order.Collections.reverse(list);
min(Collection<? extends T> coll)Returns minimum element.Collections.min(list);
max(Collection<? extends T> coll)Returns maximum element.Collections.max(list);
frequency(Collection<?> c, Object o)Counts frequency of element.Collections.frequency(list, "Java");

βœ… Example:

Example 1: Sorting and Reversing

import java.util.*;

public class CollectionsExample1 {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Aryan");
        names.add("Ashish");
        names.add("bhasker");
        names.add("Devid");

        // Sorting (Ascending Order)
        Collections.sort(names);
        System.out.println("Sorted List: " + names);

        // Reversing
        Collections.reverse(names);
        System.out.println("Reversed List: " + names);

        // Shuffling
        Collections.shuffle(names);
        System.out.println("Shuffled List: " + names);
    }
}

Output (may vary due to shuffle):

Sorted List: [Aryan, Ashish, Bhasker, Devid]
Reversed List: [Devid, Bhasker, Ashish, Aryan]
Shuffled List: [Ashish, Devid, Bhasker, Aryan]   // shuffle can change each time

Example 2: Finding Min, Max, and Frequency

import java.util.*;

public class CollectionsExample2 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(10, 20, 30, 10, 50, 10);

        int min = Collections.min(numbers);
        int max = Collections.max(numbers);
        int freq = Collections.frequency(numbers, 10);

        System.out.println("Minimum: " + min);
        System.out.println("Maximum: " + max);
        System.out.println("Frequency of 10: " + freq);
    }
}

Output:

Minimum: 10  
Maximum: 50  
Frequency of 10: 3  

Example 3: Creating Read-only and Synchronized Collections

import java.util.*;

public class CollectionsExample3 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");

        // Unmodifiable (Read-only) List
        List<String> unmodifiableList = Collections.unmodifiableList(list);
        System.out.println("Unmodifiable List: " + unmodifiableList);
        // unmodifiableList.add("Go"); // Throws UnsupportedOperationException

        // Synchronized List (Thread-safe wrapper)
        List<String> syncList = Collections.synchronizedList(list);
        System.out.println("Synchronized List: " + syncList);
    }
}

Backend developer working with Java, Spring Boot, Microservices, NoSQL, and AWS. I love sharing knowledge, practical tips, and clean code practices to help others build scalable applications.

Leave a Reply

Your email address will not be published. Required fields are marked *