AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content

14 Collections framework / Lesson 1 of 8

The collections framework — the map and how to choose

14 min · +10 XP · 2 exercises · 5 questions

Read the text14 min
Exercises0/2
Quiz5 q

Quick answer

What is the Java collections framework?

The Java collections framework is the set of data-structure interfaces and classes in java.util. Interfaces — List, Set, Queue, Deque and Map — describe what a collection does; classes such as ArrayList, HashSet, HashMap and ArrayDeque decide how, and with it the performance and iteration order. All rely on equals and hashCode and compare by contents.

java.util holds the data structures every Java program is built from: lists, sets, maps, queues. They share one design — interfaces that describe what a collection does, classes that decide how, and a small set of conventions (equals/hashCode, Iterable, fail-fast iterators, optional operations) that let them interoperate. This lesson is the map of the framework and the decision procedure for picking a structure; the following lessons take each family in depth.

The hierarchy

Iterable<E>
└── Collection<E>            — size, isEmpty, contains, add, remove, iterator, stream, …
    ├── List<E>              — ordered by index, duplicates allowed
    │   ├── ArrayList        — growable array; the default list
    │   ├── LinkedList       — doubly linked; also a Deque
    │   └── (Vector, Stack)  — legacy, synchronised; do not use
    ├── Set<E>               — no duplicates (by equals)
    │   ├── HashSet          — hash table; no order
    │   ├── LinkedHashSet    — hash table + insertion order
    │   └── TreeSet          — red-black tree; sorted (SortedSet, NavigableSet)
    └── Queue<E>             — head-first processing
        ├── PriorityQueue    — heap; smallest first
        └── Deque<E>         — both ends
            ├── ArrayDeque   — the stack and queue of choice
            └── LinkedList

Map<K, V>                    — NOT a Collection; keys → values, unique keys
├── HashMap                  — hash table; no order
├── LinkedHashMap            — + insertion (or access) order
├── TreeMap                  — sorted by key (SortedMap, NavigableMap)
├── EnumMap                  — array indexed by enum ordinal (Module 10)
├── ConcurrentHashMap        — thread-safe (Module 17)
└── (Hashtable)              — legacy, synchronised; do not use

Map is separate from Collection because a map is not a bag of elements — but its views are collections: keySet() is a Set<K>, values() a Collection<V>, entrySet() a Set<Map.Entry<K, V>>.

Interfaces first

Declare with the interface, construct with the class:

List<String> names = new ArrayList<>();
Set<Integer> seen = new HashSet<>();
Map<String, List<Order>> byCustomer = new HashMap<>();
Deque<Character> stack = new ArrayDeque<>();
Queue<Task> queue = new ArrayDeque<>();

Method parameters and return types use the interfaces (List<String>, Collection<? extends T>); a public method returning ArrayList<String> promises an implementation detail forever. The one common exception is a private field where the concrete type's extra methods are needed (LinkedHashMap.removeEldestEntry, TreeMap.firstKey) — declare it as the narrowest interface that has them (NavigableMap).

Choosing a structure

NeedUseWhy
A sequence, index access, appendsArrayListO(1) get/append; cache-friendly
A stack or queueArrayDequeO(1) at both ends; faster than LinkedList, and Stack is legacy
Unique elements, fast membershipHashSetO(1) contains
Unique, remember insertion orderLinkedHashSet+ predictable iteration
Unique, sorted, range queriesTreeSetO(log n), first/floor/subSet
Key → value lookupHashMapO(1)
Key → value, insertion order or LRULinkedHashMaporder + removeEldestEntry
Key → value, sorted / nearest keyTreeMapfloorKey, headMap, ordered iteration
Enum keys or elementsEnumMap / EnumSetarray/bit-vector speed
Always-smallest-first processingPriorityQueueO(log n) insert and poll
Frequent inserts/removes in the middle by iteratorLinkedListO(1) at the iterator — rarely the actual bottleneck
Shared across threadsConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueueModule 17

Default choices: ArrayList, HashMap, HashSet, ArrayDeque. Switch only when a measured or structural need appears (order, sorting, both-ends access).

Complexities to know cold

OperationArrayListLinkedListHashSet/HashMapTreeSet/TreeMapArrayDequePriorityQueue
get(i) / by keyO(1)O(n)O(1) avgO(log n)——
add at end / putO(1) amortisedO(1)O(1) avgO(log n)O(1)O(log n)
add at frontO(n)O(1)——O(1)—
remove by index / keyO(n)O(n) to find, O(1) to unlinkO(1) avgO(log n)O(1) at endsO(log n) poll
containsO(n)O(n)O(1) avgO(log n)O(n)O(n)
iteration orderindexindexnonesortedFIFO/LIFOnot sorted!

"avg" for hash structures assumes a decent hashCode; the worst case degrades to O(n) (or O(log n) once buckets treeify, Java 8+).

The conventions every collection follows

  • equals/hashCode on elements drive contains, remove(Object), set membership and map keys — override them on element/key classes (Module 8) or use records.
  • Iterable — every collection works with for-each and forEach; maps via their views.
  • Fail-fast iterators — modifying a collection while iterating it (other than through the iterator) throws ConcurrentModificationException (lesson 7).
  • Optional operations — immutable collections throw UnsupportedOperationException from add/remove; the interface documents which methods are optional.
  • Null policy varies: ArrayList/HashMap/HashSet allow nulls; TreeMap/TreeSet reject null keys (cannot compare); List.of/Map.of/ConcurrentHashMap reject nulls entirely.
  • toString prints contents ([a, b], {k=v}) — unlike arrays.
  • equals between collections is by contents: two lists with the same elements in order are equal; two sets with the same elements are equal, regardless of implementation class.

The utility classes

Collections (sort, reverse, shuffle, max, min, frequency, unmodifiableX, synchronizedX, emptyX, singletonX, nCopies) and Arrays (asList, sort, binarySearch, fill, copyOf, stream) hold the static helpers; List.of, Set.of, Map.of, List.copyOf (Java 9–10) create immutable collections (lesson 8).

Reading the API docs

Each interface's Javadoc specifies contracts (ordering, null policy, optional operations); each class's documents complexity and iteration order. ArrayList's says "constant amortized time" for add; HashMap's explains load factor; TreeMap's says "log(n) time cost for containsKey, get, put and remove". When choosing, read the class summary — it is written to answer exactly this question.

Interview angle

  • "ArrayList vs LinkedList?" Array-backed O(1) index access and cache locality vs linked nodes with O(1) insert/remove at a known position; ArrayList wins almost always in practice.
  • "HashMap vs TreeMap?" O(1) unordered vs O(log n) sorted with navigation methods.
  • "Why is Map not a Collection?" It maps keys to values rather than holding elements; its views are collections.
  • "Which structures reject nulls?" TreeMap/TreeSet (keys/elements), List.of/Map.of/Set.of, ConcurrentHashMap, ArrayDeque.
  • "What should you declare a variable as?" The interface — List, not ArrayList.

Key takeaways

  • Interfaces (List, Set, Map, Queue, Deque) describe behaviour; classes (ArrayList, HashMap, …) decide performance and order.
  • Defaults: ArrayList, HashMap, HashSet, ArrayDeque; Linked* for order, Tree* for sorting, PriorityQueue for smallest-first.
  • Know the complexity table and the null policies.
  • Elements need correct equals/hashCode; collections compare by contents and print their contents.

Common questions

Why is Map not a Collection in Java?

A Map associates keys with values rather than holding a bag of elements, so it does not fit Collection's contract. Its views are collections, though: keySet() is a Set, values() a Collection and entrySet() a Set of Map.Entry.

Which Java collection should I use?

Start with the defaults: ArrayList for a sequence, HashMap for key-value lookup, HashSet for unique elements and ArrayDeque for a stack or queue. Switch to LinkedHashMap or LinkedHashSet for insertion order, TreeMap or TreeSet for sorting and range queries, and PriorityQueue for smallest-first processing.

Which Java collections do not allow null?

TreeMap and TreeSet reject null keys and elements because they cannot compare them; List.of, Set.of, Map.of, ConcurrentHashMap and ArrayDeque reject nulls entirely. ArrayList, HashMap and HashSet allow them.

Should you declare a variable as List or ArrayList?

Declare it with the interface — List<String> names = new ArrayList<>() — and use interfaces for parameters and return types too. A public method returning ArrayList promises that implementation forever; the interface leaves you free to change it.

What is the time complexity of HashMap, TreeMap and ArrayList operations?

HashMap and HashSet get, put and contains are O(1) on average; TreeMap and TreeSet operations are O(log n); ArrayList get is O(1) and append O(1) amortised, while contains and insertion at the front are O(n).

Mark as readSign in to keep your place.

Java Collections Framework: Hierarchy and How to Choose

The Java collections framework in one map: List, Set, Queue and Map, their main classes, time complexities and null policies, and how to choose between them.

  • Course: Java study plan
  • Module: Collections framework
  • Kind: Lesson
  • Reading time: 14 min
  • Runtime: OpenJDK 18

What is the Java collections framework?

The Java collections framework is the set of data-structure interfaces and classes in java.util. Interfaces — List, Set, Queue, Deque and Map — describe what a collection does; classes such as ArrayList, HashSet, HashMap and ArrayDeque decide how, and with it the performance and iteration order. All rely on equals and hashCode and compare by contents.

Lesson

java.util holds the data structures every Java program is built from: lists, sets, maps, queues. They share one design — interfaces that describe what a collection does, classes that decide how, and a small set of conventions (equals/hashCode, Iterable, fail-fast iterators, optional operations) that let them interoperate. This lesson is the map of the framework and the decision procedure for picking a structure; the following lessons take each family in depth.

The hierarchy

Iterable<E>
└── Collection<E>            — size, isEmpty, contains, add, remove, iterator, stream, …
    ├── List<E>              — ordered by index, duplicates allowed
    │   ├── ArrayList        — growable array; the default list
    │   ├── LinkedList       — doubly linked; also a Deque
    │   └── (Vector, Stack)  — legacy, synchronised; do not use
    ├── Set<E>               — no duplicates (by equals)
    │   ├── HashSet          — hash table; no order
    │   ├── LinkedHashSet    — hash table + insertion order
    │   └── TreeSet          — red-black tree; sorted (SortedSet, NavigableSet)
    └── Queue<E>             — head-first processing
        ├── PriorityQueue    — heap; smallest first
        └── Deque<E>         — both ends
            ├── ArrayDeque   — the stack and queue of choice
            └── LinkedList

Map<K, V>                    — NOT a Collection; keys → values, unique keys
├── HashMap                  — hash table; no order
├── LinkedHashMap            — + insertion (or access) order
├── TreeMap                  — sorted by key (SortedMap, NavigableMap)
├── EnumMap                  — array indexed by enum ordinal (Module 10)
├── ConcurrentHashMap        — thread-safe (Module 17)
└── (Hashtable)              — legacy, synchronised; do not use

Map is separate from Collection because a map is not a bag of elements — but its views are collections: keySet() is a Set<K>, values() a Collection<V>, entrySet() a Set<Map.Entry<K, V>>.

Interfaces first

Declare with the interface, construct with the class:

List<String> names = new ArrayList<>();
Set<Integer> seen = new HashSet<>();
Map<String, List<Order>> byCustomer = new HashMap<>();
Deque<Character> stack = new ArrayDeque<>();
Queue<Task> queue = new ArrayDeque<>();

Method parameters and return types use the interfaces (List<String>, Collection<? extends T>); a public method returning ArrayList<String> promises an implementation detail forever. The one common exception is a private field where the concrete type's extra methods are needed (LinkedHashMap.removeEldestEntry, TreeMap.firstKey) — declare it as the narrowest interface that has them (NavigableMap).

Choosing a structure

NeedUseWhy
A sequence, index access, appendsArrayListO(1) get/append; cache-friendly
A stack or queueArrayDequeO(1) at both ends; faster than LinkedList, and Stack is legacy
Unique elements, fast membershipHashSetO(1) contains
Unique, remember insertion orderLinkedHashSet+ predictable iteration
Unique, sorted, range queriesTreeSetO(log n), first/floor/subSet
Key → value lookupHashMapO(1)
Key → value, insertion order or LRULinkedHashMaporder + removeEldestEntry
Key → value, sorted / nearest keyTreeMapfloorKey, headMap, ordered iteration
Enum keys or elementsEnumMap / EnumSetarray/bit-vector speed
Always-smallest-first processingPriorityQueueO(log n) insert and poll
Frequent inserts/removes in the middle by iteratorLinkedListO(1) at the iterator — rarely the actual bottleneck
Shared across threadsConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueueModule 17

Default choices: ArrayList, HashMap, HashSet, ArrayDeque. Switch only when a measured or structural need appears (order, sorting, both-ends access).

Complexities to know cold

OperationArrayListLinkedListHashSet/HashMapTreeSet/TreeMapArrayDequePriorityQueue
get(i) / by keyO(1)O(n)O(1) avgO(log n)——
add at end / putO(1) amortisedO(1)O(1) avgO(log n)O(1)O(log n)
add at frontO(n)O(1)——O(1)—
remove by index / keyO(n)O(n) to find, O(1) to unlinkO(1) avgO(log n)O(1) at endsO(log n) poll
containsO(n)O(n)O(1) avgO(log n)O(n)O(n)
iteration orderindexindexnonesortedFIFO/LIFOnot sorted!

"avg" for hash structures assumes a decent hashCode; the worst case degrades to O(n) (or O(log n) once buckets treeify, Java 8+).

The conventions every collection follows

  • equals/hashCode on elements drive contains, remove(Object), set membership and map keys — override them on element/key classes (Module 8) or use records.
  • Iterable — every collection works with for-each and forEach; maps via their views.
  • Fail-fast iterators — modifying a collection while iterating it (other than through the iterator) throws ConcurrentModificationException (lesson 7).
  • Optional operations — immutable collections throw UnsupportedOperationException from add/remove; the interface documents which methods are optional.
  • Null policy varies: ArrayList/HashMap/HashSet allow nulls; TreeMap/TreeSet reject null keys (cannot compare); List.of/Map.of/ConcurrentHashMap reject nulls entirely.
  • toString prints contents ([a, b], {k=v}) — unlike arrays.
  • equals between collections is by contents: two lists with the same elements in order are equal; two sets with the same elements are equal, regardless of implementation class.

The utility classes

Collections (sort, reverse, shuffle, max, min, frequency, unmodifiableX, synchronizedX, emptyX, singletonX, nCopies) and Arrays (asList, sort, binarySearch, fill, copyOf, stream) hold the static helpers; List.of, Set.of, Map.of, List.copyOf (Java 9–10) create immutable collections (lesson 8).

Reading the API docs

Each interface's Javadoc specifies contracts (ordering, null policy, optional operations); each class's documents complexity and iteration order. ArrayList's says "constant amortized time" for add; HashMap's explains load factor; TreeMap's says "log(n) time cost for containsKey, get, put and remove". When choosing, read the class summary — it is written to answer exactly this question.

Interview angle

  • "ArrayList vs LinkedList?" Array-backed O(1) index access and cache locality vs linked nodes with O(1) insert/remove at a known position; ArrayList wins almost always in practice.
  • "HashMap vs TreeMap?" O(1) unordered vs O(log n) sorted with navigation methods.
  • "Why is Map not a Collection?" It maps keys to values rather than holding elements; its views are collections.
  • "Which structures reject nulls?" TreeMap/TreeSet (keys/elements), List.of/Map.of/Set.of, ConcurrentHashMap, ArrayDeque.
  • "What should you declare a variable as?" The interface — List, not ArrayList.

Key takeaways

  • Interfaces (List, Set, Map, Queue, Deque) describe behaviour; classes (ArrayList, HashMap, …) decide performance and order.
  • Defaults: ArrayList, HashMap, HashSet, ArrayDeque; Linked* for order, Tree* for sorting, PriorityQueue for smallest-first.
  • Know the complexity table and the null policies.
  • Elements need correct equals/hashCode; collections compare by contents and print their contents.

Common questions

Why is Map not a Collection in Java?

A Map associates keys with values rather than holding a bag of elements, so it does not fit Collection's contract. Its views are collections, though: keySet() is a Set, values() a Collection and entrySet() a Set of Map.Entry.

Which Java collection should I use?

Start with the defaults: ArrayList for a sequence, HashMap for key-value lookup, HashSet for unique elements and ArrayDeque for a stack or queue. Switch to LinkedHashMap or LinkedHashSet for insertion order, TreeMap or TreeSet for sorting and range queries, and PriorityQueue for smallest-first processing.

Which Java collections do not allow null?

TreeMap and TreeSet reject null keys and elements because they cannot compare them; List.of, Set.of, Map.of, ConcurrentHashMap and ArrayDeque reject nulls entirely. ArrayList, HashMap and HashSet allow them.

Should you declare a variable as List or ArrayList?

Declare it with the interface — List<String> names = new ArrayList<>() — and use interfaces for parameters and return types too. A public method returning ArrayList promises that implementation forever; the interface leaves you free to change it.

What is the time complexity of HashMap, TreeMap and ArrayList operations?

HashMap and HashSet get, put and contains are O(1) on average; TreeMap and TreeSet operations are O(log n); ArrayList get is O(1) and append O(1) amortised, while contains and insertion at the front are O(n).

Exercises

Pick the structure

Read an integer n and n words. Using the right structure for each job, print: first=<first word> and last=<last word> (from a List), distinct=<count> (a HashSet), sorted=<distinct words in natural order, space-separated> (a TreeSet), inOrder=<distinct words in first-seen order> (a LinkedHashSet), and top=<the most frequent word; ties broken by natural order> (a HashMap of counts).

Example: 5 then b a b c a →

first=b last=a
distinct=3
sorted=a b c
inOrder=b a c
top=a

Choose by workload

Encode the framework's decision table. Read n lines, each a workload described by flags: kind=<list|set|map|queue> plus zero or more of sorted, ordered (insertion order), lifo, priority. Print the default class for each: list → ArrayList; set → HashSet, LinkedHashSet if ordered, TreeSet if sorted; map → HashMap/LinkedHashMap/TreeMap likewise; queue → ArrayDeque, or PriorityQueue if priority (lifo is still ArrayDeque, used as a stack). sorted beats ordered when both appear.

Example: 3 then kind=set ordered, kind=map sorted, kind=queue priority →

LinkedHashSet
TreeMap
PriorityQueue

In this module: Collections framework

← Checkpoint — Generics · Lists — ArrayList, LinkedList and the List API →