Skip to content
QuizMaker logoQuizMaker
Activity
Java Programming: From Zero to Enterprise
4. Advanced Java & Frameworks
1. Getting Started with Java & the JVM
2. Data Types & Variables
3. Control Flow: Ifs & Loops
4. String Manipulation in Depth
5. Methods (Functions) Architecture
6. Arrays & The Enhanced For Loop
7. User Input via Scanner
8. Mathematical Operations & The Math Class
9. Operators in Depth
10. Block Scope & Variable Lifecycles
11. Introduction to Object-Oriented Programming
12. Classes & Instances Deep Dive
13. Constructors
14. Encapsulation & The 'this' Keyword
15. Inheritance: Extending Functionality
16. Polymorphism & Method Overriding
17. Abstraction & Abstract Classes
18. Interfaces: The Ultimate Contract
19. Packages & Access Modifiers
20. Enums (Enumerations)
21. Exceptions: Handling Runtime Errors
22. The 'throw' and 'throws' keywords
23. Dates, Times, and Formatting
24. Enumerable Data Structures
25. LinkedLists: The Alternative
26. HashMaps: Key-Value Architecture
27. HashSets: The Art of Uniqueness
28. Iterator: Safe Collection Traversal
29. Wrapper Classes & Autoboxing
30. Basic File I/O
31. Generics: Type-Safe Templates
32. Lambda Expressions & Functional Interfaces
33. The Stream API: Functional Data Pipelines
34. Optional: Beating the NullPointerException
35. Multithreading & Concurrency Basics
36. JDBC: Connecting to SQL Databases
37. Annotations & Reflection
38. The JVM Garbage Collector
39. Introduction to Spring Boot
40. Unit Testing with JUnit
41. Java Collections for DSA
CONTENTS

41. Java Collections for DSA

Master the Java Collections Framework through the lens of Data Structures and Algorithms—know when to use what and why.

Java Programming: From Zero to Enterprise
4. Advanced Java & Frameworks
February 22, 2026
71
A

[!NOTE] In DSA interviews and competitive programming, choosing the right data structure is often more important than choosing the right algorithm. This chapter is your comprehensive reference for Java's built-in data structures, their time complexities, and exactly when to reach for each one.

The Collections Framework Hierarchy

Java's Collections Framework is a unified architecture for representing and manipulating groups of data. Everything descends from two root interfaces:

                    Iterable
                       |
                   Collection
                  /    |     \
               List   Set   Queue
              /   \    |  \     \
      ArrayList  LinkedList  HashSet  TreeSet  PriorityQueue  ArrayDeque
                              |
                        LinkedHashSet

                      Map (separate hierarchy)
                     /    |        \
                HashMap  TreeMap  LinkedHashMap

Key insight: Map does NOT extend Collection. It's a completely separate inheritance tree because maps store key-value pairs, not individual elements.

The Big-O Cheat Sheet

This is the single most important table for DSA. Memorize it.

List Implementations

Operation ArrayList LinkedList
get(index)O(1) ✅O(n) ❌
add(end)O(1) amortizedO(1)
add(index)O(n) — shifts elementsO(n) — traversal
remove(index)O(n) — shifts elementsO(n) — traversal
contains()O(n)O(n)
MemoryContiguous arrayNode pointers (more overhead)

DSA verdict: Use ArrayList 99% of the time. LinkedList is only better when you're doing heavy insert/remove at the head/tail AND never doing random access.

Set Implementations

Operation HashSet TreeSet LinkedHashSet
add()O(1) avgO(log n)O(1) avg
remove()O(1) avgO(log n)O(1) avg
contains()O(1) avgO(log n)O(1) avg
OrderingNoneSorted ✅Insertion order
floor/ceiling❌O(log n) ✅❌

Map Implementations

Operation HashMap TreeMap LinkedHashMap
put()O(1) avgO(log n)O(1) avg
get()O(1) avgO(log n)O(1) avg
remove()O(1) avgO(log n)O(1) avg
OrderingNoneSorted by key ✅Insertion order
floorKey/ceilingKey❌O(log n) ✅❌

Queue/Stack Implementations

Operation PriorityQueue (Min-Heap) ArrayDeque (Stack/Queue)
offer/pushO(log n)O(1)
poll/popO(log n)O(1)
peekO(1)O(1)
containsO(n)O(n)

PriorityQueue (Min-Heap / Max-Heap)

The PriorityQueue is the single most important DSA collection. It's a binary heap that always gives you the minimum (or maximum) element in O(1) peek and O(log n) insert/remove.

// Min-Heap (default) — smallest element first
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(30);
minHeap.offer(10);
minHeap.offer(20);
minHeap.poll();  // Returns 10 (smallest)
minHeap.peek();  // Returns 20 (next smallest)

// Max-Heap — largest element first
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.offer(30);
maxHeap.offer(10);
maxHeap.offer(20);
maxHeap.poll();  // Returns 30 (largest)

// Custom comparator — sort by frequency, then alphabetically
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
    if (a[1] != b[1]) return b[1] - a[1]; // Higher frequency first
    return a[0] - b[0]; // Then by value ascending
});

DSA use cases: Kth largest/smallest element, merge K sorted lists, Dijkstra's shortest path, task scheduling, median finding (two heaps), top-K frequent elements.

ArrayDeque (Stack + Queue)

ArrayDeque is the universal replacement for both Stack and LinkedList when used as a stack or queue. It's faster than both because it uses a resizable array with no node overhead.

// As a Stack (LIFO) — use push/pop/peek
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);    // [1]
stack.push(2);    // [2, 1]
stack.push(3);    // [3, 2, 1]
stack.pop();      // Returns 3
stack.peek();     // Returns 2

// As a Queue (FIFO) — use offer/poll/peek
Deque<Integer> queue = new ArrayDeque<>();
queue.offer(1);   // [1]
queue.offer(2);   // [1, 2]
queue.offer(3);   // [1, 2, 3]
queue.poll();     // Returns 1
queue.peek();     // Returns 2

[!CAUTION] Never use java.util.Stack in production or interviews. It extends Vector (synchronized, slow) and is a legacy class. Always use ArrayDeque instead. Interviewers will notice.

DSA use cases: BFS (queue), DFS (stack), parenthesis matching, monotonic stack, sliding window maximum, backtracking.

TreeMap & TreeSet (Sorted Structures)

When you need elements automatically sorted and want to do range queries, floor/ceiling lookups, or find the next greater/smaller element in O(log n) — use TreeMap or TreeSet.

TreeMap<Integer, String> map = new TreeMap<>();
map.put(10, "ten");
map.put(20, "twenty");
map.put(30, "thirty");

map.firstKey();        // 10 (smallest key)
map.lastKey();         // 30 (largest key)
map.floorKey(25);      // 20 (largest key ≤ 25)
map.ceilingKey(25);    // 30 (smallest key ≥ 25)
map.subMap(10, 30);    // {10=ten, 20=twenty} (range query, end exclusive)

TreeSet<Integer> set = new TreeSet<>();
set.add(5); set.add(15); set.add(25);
set.floor(20);         // 15
set.ceiling(20);       // 25
set.headSet(20);       // [5, 15] (elements < 20)

DSA use cases: Interval problems, skyline problem, ordered statistics, range queries, calendar scheduling, finding closest values.

HashMap — The DSA Workhorse

You already learned HashMap in Chapter 26. Here's the DSA-specific perspective:

// Frequency counting (THE most common DSA pattern)
Map<Character, Integer> freq = new HashMap<>();
for (char c : str.toCharArray()) {
    freq.put(c, freq.getOrDefault(c, 0) + 1);
}

// Two Sum pattern — store complement
Map<Integer, Integer> seen = new HashMap<>(); // value → index
for (int i = 0; i < nums.length; i++) {
    int complement = target - nums[i];
    if (seen.containsKey(complement)) {
        return new int[]{seen.get(complement), i};
    }
    seen.put(nums[i], i);
}

// Group Anagrams pattern — key = sorted string
Map<String, List<String>> groups = new HashMap<>();
for (String word : words) {
    char[] chars = word.toCharArray();
    Arrays.sort(chars);
    String key = new String(chars);
    groups.computeIfAbsent(key, k -> new ArrayList<>()).add(word);
}

DSA use cases: Two Sum, frequency counting, anagram grouping, substring problems, graph adjacency lists, memoization/caching.

DSA Pattern → Collection Mapping

When you see a problem pattern, reach for the right collection immediately:

DSA Pattern Recommended Collection Why
Frequency countingHashMap<T, Integer>O(1) lookup/update
Two Sum / complementHashMap<Integer, Integer>O(1) complement check
Sliding window (unique)HashSet or HashMapO(1) contains check
BFS traversalArrayDeque (as Queue)FIFO order, O(1) ops
DFS traversal (iterative)ArrayDeque (as Stack)LIFO order, O(1) ops
Kth largest/smallestPriorityQueueO(log k) maintain heap of size k
Merge K sorted listsPriorityQueueAlways extract global min in O(log k)
Monotonic stackArrayDeque (as Stack)Next greater/smaller element
Parenthesis matchingArrayDeque (as Stack)LIFO matching of open/close
Interval problemsTreeMapfloor/ceiling for overlaps
LRU CacheLinkedHashMapInsertion-order + O(1) access
Topological sortHashMap + ArrayDequeAdjacency list + BFS queue
Union-Find / visitedHashSetO(1) membership check
Sorted order neededTreeMap or TreeSetAuto-sorted, O(log n) ops

Common Gotchas in DSA Interviews

  1. HashMap Key Requirements

Objects used as HashMap keys must properly override hashCode() and equals(). If you use arrays as keys, they compare by reference, not content!

// WRONG — arrays use identity for equals/hashCode
Map<int[], Integer> map = new HashMap<>();
map.put(new int[]{1, 2}, 1);
map.get(new int[]{1, 2}); // Returns NULL! Different object reference.

// RIGHT — convert to String or List for content-based hashing
Map<String, Integer> map = new HashMap<>();
map.put(Arrays.toString(new int[]{1, 2}), 1);
map.get(Arrays.toString(new int[]{1, 2})); // Returns 1 ✅

  1. PriorityQueue Is NOT Sorted Iteration

Iterating a PriorityQueue does NOT give elements in sorted order. Only poll() guarantees min/max extraction:

PriorityQueue<Integer> pq = new PriorityQueue<>(List.of(3, 1, 4, 1, 5));

// WRONG — iterator order is NOT guaranteed sorted
for (int x : pq) System.out.print(x + " "); // Could print: 1 1 4 3 5

// RIGHT — poll() extracts in sorted order
while (!pq.isEmpty()) System.out.print(pq.poll() + " "); // 1 1 3 4 5

  1. ConcurrentModificationException

Never modify a collection while iterating it with a for-each loop. Use an Iterator with remove(), or collect items to remove separately.

// WRONG — crashes!
for (String s : list) {
    if (s.startsWith("x")) list.remove(s); // ConcurrentModificationException
}

// RIGHT — use Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().startsWith("x")) it.remove(); // Safe
}

  1. Collections.sort() vs Arrays.sort()

Use Arrays.sort() for arrays, Collections.sort() for Lists. For primitives, Arrays.sort() uses dual-pivot quicksort (O(n log n) avg). For objects, it uses TimSort (O(n log n) guaranteed).

int[] arr = {5, 3, 1, 4, 2};
Arrays.sort(arr); // [1, 2, 3, 4, 5]

List<Integer> list = Arrays.asList(5, 3, 1, 4, 2);
Collections.sort(list); // [1, 2, 3, 4, 5]

// Custom comparator (sort descending)
Arrays.sort(intervals, (a, b) -> a[0] - b[0]); // Sort 2D by first element
list.sort(Comparator.reverseOrder()); // [5, 4, 3, 2, 1]

Collections Utility Methods You Must Know

Collections.sort(list);            // Sort a List
Collections.reverse(list);         // Reverse a List
Collections.swap(list, i, j);     // Swap elements at indices i and j
Collections.frequency(list, obj); // Count occurrences of obj
Collections.min(collection);      // Find minimum element
Collections.max(collection);      // Find maximum element
Collections.unmodifiableList(list); // Return read-only view

// Initialization shortcuts
List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
Set<String> set = new HashSet<>(Set.of("a", "b", "c"));
Map<String, Integer> map = new HashMap<>(Map.of("a", 1, "b", 2));

[!TIP] DSA Interview Summary: When in doubt: HashMap for O(1) lookups, PriorityQueue for top-K/Kth problems, ArrayDeque for any stack/queue needs, TreeMap when you need sorted keys or floor/ceiling. Master these four and you can solve 90% of DSA problems efficiently.

How to Choose Quickly in Interviews

When solving DSA problems in Java, decide by operation first. Ask what must be fast: lookup, ordered lookup, queue behavior, stack behavior, top-K extraction, or index access. The answer usually points to the collection.

Fast Decision Checklist

Problem clueLikely choice
Need frequency countsHashMap<T, Integer>
Need unique visited valuesHashSet<T>
Need BFS orderArrayDeque<T> as queue
Need DFS iterativeArrayDeque<T> as stack
Need kth largest or smallestPriorityQueue<T>
Need sorted keys or floor/ceilingTreeMap<K, V>

Starter Template

Map<Integer, Integer> frequency = new HashMap<>();
for (int value : nums) {
    frequency.put(value, frequency.getOrDefault(value, 0) + 1);
}

Common Interview Mistakes

  • Using Stack instead of ArrayDeque.
  • Using array objects directly as map keys.
  • Sorting when a heap or hash lookup would be cheaper.
  • Forgetting to state average-case vs worst-case complexity for hash structures.

Mini Practice

Solve these mentally first: two sum, valid parentheses, top K frequent elements, first unique character, and merge K sorted lists. For each, write only the Java collection you would start with and why.

Practice Lab: Pick the Right Collection

For each problem, choose the Java collection first, then explain the operation that must be fast.

  1. Two Sum: choose the structure for complement lookup.
  2. Valid Parentheses: choose the structure for last-open-first-close behavior.
  3. Top K Frequent: choose the structures for counting and extracting top values.
  4. First Unique Character: choose the structure for frequency counting.
  5. Merge K Sorted Lists: choose the structure for repeatedly getting the smallest current element.

Goal: Build the habit of matching problem clues to collection operations and complexity.

Revision Checkpoint

  • HashMap: Frequency, lookup, grouping.
  • HashSet: Uniqueness and visited tracking.
  • ArrayDeque: Stack and queue behavior.
  • PriorityQueue: Heap for top-K and repeated min/max extraction.
  • TreeMap: Sorted keys and floor/ceiling operations.

Before the quiz: Match five common DSA patterns to the first Java collection you would reach for.

Share this article

Share on TwitterShare on LinkedInShare on FacebookShare on WhatsAppShare on Email

Test your knowledge

Take a quick quiz based on this chapter.

hardJava
Quiz: Collections for DSA
10 questions5 min
Lesson 11 of 11 in 4. Advanced Java & Frameworks
Previous in 4. Advanced Java & Frameworks
40. Unit Testing with JUnit
Completed!
You've finished this course
Back to Java Programming: From Zero to Enterprise
Back to moduleCategories