THE MODN CHRONICLES

Interview Prep

Interview Questions on Collection Framework in Java — List, Set, Map, and Internal Working

The Java Collection Framework is tested in every Java interview — from campus placements to senior developer rounds. Interviewers do not just ask “what is ArrayList?” They ask how HashMap works internally, when to use LinkedHashMap, and how ConcurrentHashMap handles thread safety. Here is the deep dive.

Java collection framework code on screen

The Collection Framework is the most tested Java topic after OOPs. Every interview from TCS to Amazon asks about it.

Why Collection Framework Dominates Java Interviews

The Java Collection Framework provides the data structures that every Java application uses — List, Set, Map, Queue. In interviews, it is the bridge between theory (data structures) and practice (which Java class to use). Interviewers test three things: which collection to use for a given scenario, how the collection works internally, and the performance characteristics (Big O) of each operation.

This guide goes deeper than basic definitions. It covers the internal working of HashMap, the difference between fail-fast and fail-safe iterators, and the concurrent collections that senior interviews test.

“How does HashMap work internally?” is the single most asked Java interview question in India. If you cannot explain hashing, buckets, and collision handling, the interview is over.

Collection Framework Hierarchy

Q1: Draw the Collection Framework hierarchy.

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

                    Map (separate hierarchy)
                   / | \
            HashMap  TreeMap  Hashtable
               |
         LinkedHashMap
               |
      ConcurrentHashMap

Key interfaces:
- Collection → root interface (add, remove, contains)
- List → ordered, allows duplicates, index access
- Set → no duplicates
- Queue → FIFO ordering
- Map → key-value pairs (NOT part of Collection interface)

// This hierarchy question is asked in 80% of interviews.
// Draw it from memory.

List Interface Deep Dive

Q2: ArrayList vs LinkedList vs Vector — complete comparison.

Feature        ArrayList       LinkedList      Vector
──────────     ──────────      ──────────      ──────────
Internal       Dynamic array   Doubly linked   Dynamic array
                               list
Access         O(1) random     O(n) random     O(1) random
Insert/Delete  O(n) middle     O(1) if at node O(n) middle
Thread-safe    No              No              Yes (synchronized)
Growth         50% increase    N/A             100% increase
Memory         Less overhead   More (pointers) Less overhead
Iterator       Fail-fast       Fail-fast       Fail-fast

// When to use:
// ArrayList → default choice (95% of cases)
// LinkedList → frequent insert/delete at both ends (Queue)
// Vector → legacy, use Collections.synchronizedList() instead

// ArrayList internal working:
// Default capacity: 10
// When full: creates new array of size (old * 1.5)
// Copies all elements to new array
// This is why add() is amortized O(1) but worst case O(n)

ArrayList<String> list = new ArrayList<>(50); // set initial capacity
// If you know the size, set initial capacity to avoid resizing

Q3: How do you make an ArrayList thread-safe?

// Method 1: Collections.synchronizedList()
List<String> syncList = Collections.synchronizedList(
    new ArrayList<>()
);
// Wraps every method with synchronized block
// Must manually synchronize during iteration:
synchronized (syncList) {
    for (String s : syncList) {
        System.out.println(s);
    }
}

// Method 2: CopyOnWriteArrayList (preferred for read-heavy)
List<String> cowList = new CopyOnWriteArrayList<>();
// Creates a new copy of array on every write
// Reads are lock-free (fast)
// Writes are expensive (copies entire array)
// Best for: read-heavy, write-rare scenarios (listeners)

// Method 3: Vector (legacy — avoid)
Vector<String> vector = new Vector<>();
// Every method is synchronized — too much overhead

Map Interface — The Most Tested Topic

Q4: How does HashMap work internally? (Complete answer)

// HashMap = array of buckets (Node<K,V>[])
// Each bucket = linked list (or tree if > 8 nodes)

// PUT operation:
// 1. key.hashCode() → raw hash
// 2. hash = hash ^ (hash >>> 16) → spread bits
// 3. index = hash & (capacity - 1) → bucket index
// 4. If bucket empty → store Node directly
// 5. If bucket has nodes:
//    a. Check each node: if key.equals(existingKey)
//       → update value (replace)
//    b. If no match → add to end of linked list
//    c. If list length > 8 → convert to red-black tree

// GET operation:
// 1. Calculate hash → find bucket index
// 2. Traverse bucket (list or tree)
// 3. Use equals() to find exact key match

// Key constants:
// Default capacity: 16
// Load factor: 0.75 (resize when 75% full)
// Treeify threshold: 8 (list → tree)
// Untreeify threshold: 6 (tree → list)

// Resize (rehashing):
// When size > capacity * loadFactor
// New capacity = old capacity * 2
// ALL entries are rehashed to new buckets
// This is expensive — set initial capacity if possible

HashMap<String, Integer> map = new HashMap<>(100, 0.75f);

Q5: HashMap vs Hashtable vs ConcurrentHashMap

Feature          HashMap         Hashtable       ConcurrentHashMap
──────────       ──────────      ──────────      ──────────────────
Thread-safe      No              Yes (all sync)  Yes (segment-level)
Null keys        1 null key      No null keys    No null keys
Null values      Multiple        No null values  No null values
Performance      Fastest         Slowest         Fast (concurrent)
Iterator         Fail-fast       Fail-fast       Weakly consistent
Since            Java 1.2        Java 1.0        Java 1.5

// ConcurrentHashMap internal (Java 8+):
// Uses CAS (Compare-And-Swap) + synchronized blocks
// Only locks the specific bucket being modified
// Multiple threads can read/write different buckets simultaneously
// Much better than Hashtable which locks the entire map

// When to use:
// HashMap → single-threaded (default choice)
// ConcurrentHashMap → multi-threaded
// Hashtable → never (legacy)

Q6: What happens if two keys have the same hashCode?

This is a collision. Both keys go to the same bucket. HashMap stores them as a linked list in that bucket. When retrieving, it traverses the list and uses equals() to find the exact key. If the list grows beyond 8 nodes (Java 8+), it converts to a red-black tree for O(log n) lookup instead of O(n).

Follow-up: “What is the contract between hashCode() and equals()?” — If two objects are equal (equals() returns true), they MUST have the same hashCode. But two objects with the same hashCode are NOT necessarily equal. Breaking this contract causes HashMap to malfunction.

Java developer working on collections code

HashMap internals is the most asked Java question. Know hashing, buckets, collisions, and the treeification threshold.

Set and Queue

Q7: How does HashSet work internally?

HashSet uses HashMap internally. Every element you add to a HashSet is stored as a KEY in an internal HashMap, with a dummy constant object as the value. When you call set.add("hello"), it internally calls map.put("hello", PRESENT) where PRESENT is a static dummy Object. This is why HashSet does not allow duplicates — HashMap does not allow duplicate keys.

Q8: What is the difference between Comparable and Comparator?

// Comparable — natural ordering (inside the class)
class Student implements Comparable<Student> {
    String name;
    int marks;
    
    @Override
    public int compareTo(Student other) {
        return this.marks - other.marks; // ascending by marks
    }
}
Collections.sort(students); // uses compareTo()

// Comparator — custom ordering (outside the class)
Comparator<Student> byName = (s1, s2) -> 
    s1.name.compareTo(s2.name);
Collections.sort(students, byName);

// Multiple sort criteria:
Comparator<Student> byMarksDesc = 
    Comparator.comparingInt(Student::getMarks).reversed();
Comparator<Student> byNameThenMarks = 
    Comparator.comparing(Student::getName)
              .thenComparingInt(Student::getMarks);

// Key difference:
// Comparable = single natural order, modifies the class
// Comparator = multiple custom orders, external to class

Q9: What is the difference between fail-fast and fail-safe iterators?

// Fail-fast: throws ConcurrentModificationException
// if collection is modified during iteration
// ArrayList, HashMap, HashSet use fail-fast iterators

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));
for (String s : list) {
    list.remove(s); // ConcurrentModificationException!
}

// Safe way to remove during iteration:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("b")) {
        it.remove(); // safe — uses iterator's remove()
    }
}

// Fail-safe: works on a COPY of the collection
// CopyOnWriteArrayList, ConcurrentHashMap use fail-safe
// No exception, but may not reflect latest changes

CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>();
// Iterating while modifying is safe here

How to Prepare

Collection Framework — Priority by Experience

Freshers

  • • Hierarchy diagram
  • • ArrayList vs LinkedList
  • • HashMap basics
  • • HashSet usage
  • • Comparable vs Comparator

2-4 Years

  • • HashMap internals (complete)
  • • hashCode/equals contract
  • • Fail-fast vs fail-safe
  • • TreeMap/TreeSet
  • • Collections utility class

5+ Years

  • • ConcurrentHashMap internals
  • • CopyOnWriteArrayList
  • • BlockingQueue
  • • Custom collection design
  • • Performance tuning

Practice Java Collection Questions with AI

Get asked real Collection Framework interview questions. Explain HashMap internals, compare implementations, and receive instant feedback.

Free · AI-powered feedback · Collection-specific questions