Java Collections Framework

The Java Collections Framework is Java's toolbox for storing groups of objects: lists, sets, queues, and maps. Instead of building your own data structures, you pick a tested one like ArrayList or HashMap. This guide walks through the collection hierarchy, what each interface is for, and how to choose the right one.

What is the Collections Framework?

It's a set of interfaces (what a collection can do) and classes (how it does it) in the java.util package. Think of a kitchen: you have a cutlery tray (ordered slots), a spice rack (one of each), and labelled jars (look up by name). Each container suits a different job.

Why not just use arrays?

Arrays have a fixed size. Once you create new String[10], you can't add an 11th item. Collections grow and shrink automatically and come with handy methods like contains(), remove(), and sorting.

The Java collection hierarchy

Everything is built on interfaces, so your code can depend on a type of collection (like List) rather than a specific class (like ArrayList):

The core collection interfaces

InterfaceOrderDuplicatesMain useGo-to class
ListInsertion order, indexed✔ AllowedA sequence of itemsArrayList
SetNone (depends on class)✘ Not allowedUnique items, fast "contains?"HashSet
Queue / DequeProcessing order✔ AllowedWaiting lines, stacksArrayDeque
MapNone (depends on class)Keys uniqueLook up a value by keyHashMap

Which collection should I use?

Start from what you need, not from the class names. Pick a need below:

Pick what you need

Ordered, duplicates OK

Use a List, normally ArrayList.

  • Keeps insertion order
  • Allows duplicates
  • Fast access by index: list.get(3)
  • Example: items in a shopping cart
List<String> cart = new ArrayList<>();
cart.add("Milk");
cart.add("Milk");   // duplicates allowed

Unique items only

Use a Set, normally HashSet. Use LinkedHashSet to keep insertion order or TreeSet to keep it sorted.

  • No duplicates
  • Very fast contains() checks
  • Example: unique visitor IDs
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("java");   // ignored, already present

Look up by key

Use a Map, normally HashMap. Use LinkedHashMap for insertion order or TreeMap for sorted keys.

  • Stores key → value pairs
  • Keys are unique
  • Example: username → user profile
Map<String, Integer> stock = new HashMap<>();
stock.put("apples", 12);
stock.get("apples");   // 12

Process in order

Use a Queue/Deque, normally ArrayDeque, or PriorityQueue to process the smallest or most urgent item first.

  • First in, first out (FIFO), or last in, first out as a stack
  • Example: print jobs, undo history
Deque<String> jobs = new ArrayDeque<>();
jobs.offer("print A");
jobs.offer("print B");
jobs.poll();   // "print A"
Most real code uses just four classes: ArrayList, HashSet, HashMap, and ArrayDeque. Reach for the others when you need ordering, sorting, or priority.

Comparing the main implementations

"Fast" means the time stays roughly constant as the collection grows; "slower" grows with size.
ClassKeeps order?Lookup / containsGood to know
ArrayListInsertionBy index: fast · by value: slowerBest default list
LinkedListInsertionSlowerRarely the best choice; ArrayDeque is usually faster as a queue
HashSet / HashMapNoFastElements need proper equals() and hashCode()
LinkedHashSet / LinkedHashMapInsertionFastSlightly more memory than Hash versions
TreeSet / TreeMapSortedMedium (logarithmic)Supports ranges like "everything after X"
ArrayDequeBoth endsFast at endsBest queue and stack
PriorityQueueBy priorityFast to peek at smallestIteration order isn't sorted, only removal order

Let's see it in action

Here's one small program using a List, a Set, and a Map together, counting words in a sentence:

import java.util.*;

public class WordStats {
    public static void main(String[] args) {
        List<String> words = List.of("the", "cat", "sat", "on", "the", "mat");

        Set<String> unique = new TreeSet<>(words);          // removes duplicates, keeps sorted
        Map<String, Integer> counts = new TreeMap<>();
        for (String w : words) {
            counts.merge(w, 1, Integer::sum);               // add 1 to this word's count
        }

        System.out.println("All words:    " + words);
        System.out.println("Unique words: " + unique);
        System.out.println("Counts:       " + counts);
    }
}
All words:    [the, cat, sat, on, the, mat]
Unique words: [cat, mat, on, sat, the]
Counts:       {cat=1, mat=1, on=1, sat=1, the=2}
  • List.of(...) — a quick, unmodifiable list.
  • new TreeSet<>(words) — copies the words into a sorted set, so the duplicate "the" disappears.
  • counts.merge(w, 1, Integer::sum) — "put 1 if the word is new, otherwise add 1 to what's there".

Tip: declare variables with the interface type

List<String> names = new ArrayList<>();     // ✔ preferred
ArrayList<String> names2 = new ArrayList<>();  // works, but ties your code to one class

If you later need a different list implementation, you change one word, and the rest of the code keeps working. The <String> part is a generic type; it tells Java the collection holds Strings, so the compiler stops you from adding anything else.

Helpful utilities: Collections and factory methods

  • List.of(...), Set.of(...), Map.of(...) — create small unmodifiable collections in one line (Java 9+).
  • Collections.sort(list), Collections.reverse(list), Collections.max(c) — static helpers in the Collections utility class. Note the plural "s".
  • Collections.unmodifiableList(list) — a read-only view of an existing list.

Thread safety: ArrayList, HashMap, and the other standard classes are not safe to modify from several threads at once. See thread-safe lists in Java for the options.

Quick recap

  • The Collections Framework is a set of interfaces and classes in java.util.
  • List = ordered with duplicates, Set = unique, Queue = processing order, Map = key → value.
  • Map is part of the framework but doesn't extend Collection.
  • Defaults: ArrayList, HashSet, HashMap, ArrayDeque.
  • Declare variables using the interface type: List<String> x = new ArrayList<>().

What's next?

Get hands-on with the most-used collection in Java ArrayList (and how to sort it), then learn to share lists safely between threads in thread-safe lists.

Frequently Asked Questions

What is the Java Collections Framework?

It's the set of ready-made interfaces and classes in java.util for storing and working with groups of objects: lists, sets, queues, and maps. It gives you tested data structures like ArrayList and HashMap so you don't have to build your own.

Is Map part of the Collection hierarchy?

Map is part of the Collections Framework, but it does not extend the Collection interface. A Map stores key-value pairs rather than single elements, so it has its own hierarchy. You can still view a map's keys, values, or entries as collections.

What is the difference between List and Set in Java?

A List keeps elements in order and allows duplicates, and you can access items by position. A Set doesn't allow duplicates: adding an element that's already there has no effect. Use a Set when uniqueness matters, such as a set of email addresses.

What is the difference between Collection and Collections?

Collection (singular) is the root interface that List, Set, and Queue extend. Collections (plural) is a utility class full of static helper methods such as Collections.sort(), Collections.reverse(), and Collections.unmodifiableList().

Which collection should I use by default?

For most code: ArrayList when you need a list, HashSet for unique items, HashMap for key-value lookups, and ArrayDeque for a queue or stack. Switch to a specialised implementation only when you need sorting, insertion order, or thread safety.