Programming in Java

Unit 13: Collections Framework

Master Java's powerful Collections Framework โ€” from ArrayList to HashMap internals โ€” and build production-grade data management systems used at Flipkart, IRCTC, and every Indian tech company.

โฑ๏ธ 8 hrs theory + 6 hrs lab  |  ๐Ÿ’ฐ Earning Potential: โ‚น10Kโ€“โ‚น30K/month  |  ๐Ÿ“ 30 MCQs (Bloom's Mapped)

๐Ÿ’ผ Jobs this unlocks: Java Backend Developer (โ‚น5โ€“10 LPA)  |  Software Engineer (โ‚น6โ€“15 LPA)  |  Data Processing Developer (โ‚น4โ€“8 LPA)

Section A

Opening Hook โ€” Flipkart Big Billion Day: How Collections Power India's Biggest Sale

๐Ÿ›’ Behind the Scenes of Flipkart's Big Billion Day

Every year, Flipkart's Big Billion Day sale handles 50 million products in its catalog, 1.5 million orders per hour, and flash deals that expire in seconds. How does the system instantly find any product among 50 million? How does it countdown flash deals in perfect priority order? How does your cart grow and shrink dynamically?

The secret weapon: Java Collections Framework.

โ€ข HashMap powers the product catalog โ€” 50 million products mapped by product ID, giving O(1) instant lookup. Search "iPhone 16"? HashMap finds it in constant time, whether there are 50 products or 50 million.

โ€ข PriorityQueue manages the flash deal countdown โ€” deals expiring soonest automatically bubble to the top. No manual sorting needed.

โ€ข ArrayList handles your cart โ€” dynamically growing as you add items, supporting instant access by index to display "Item 3 of 7 in your cart".

What if YOU built this? What if you could design systems that handle millions of data points with zero-lag lookups? That's exactly what this unit teaches you โ€” the data structures that power every serious Java application in India.

๐Ÿ‡ฎ๐Ÿ‡ณ Flipkart๐Ÿ‡ฎ๐Ÿ‡ณ IRCTC๐Ÿ‡ฎ๐Ÿ‡ณ PhonePe๐Ÿ‡ฎ๐Ÿ‡ณ Zomato๐Ÿ‡ฎ๐Ÿ‡ณ Paytm๐Ÿ‡ฎ๐Ÿ‡ณ Zerodha
Java Collections is the #1 most-asked topic in Indian tech interviews. According to InterviewBit (2024), 78% of Java interviews at TCS, Infosys, Wipro, and product companies like Flipkart include at least 2โ€“3 questions on Collections Framework. Master this unit, and you've unlocked the single most valuable interview topic.
Section B

Learning Outcomes โ€” Bloom's Taxonomy Mapped (12 Outcomes)

Bloom's LevelLearning Outcome
๐Ÿ”ต RememberLO1: List all core interfaces in the Collection hierarchy (Collection, List, Set, Queue, Map) and name at least two implementing classes for each
๐Ÿ”ต RememberLO2: State the time complexity of fundamental operations (add, get, remove, contains) for ArrayList, LinkedList, HashSet, and HashMap
๐ŸŸข UnderstandLO3: Explain the internal working of HashMap โ€” hashing, buckets, linked list chaining, and tree conversion at threshold 8
๐ŸŸข UnderstandLO4: Distinguish between Comparable (natural ordering) and Comparator (custom ordering) with real-world Indian examples
๐ŸŸก ApplyLO5: Write a complete Student Result Management System using ArrayList, HashMap, and Collections.sort()
๐ŸŸก ApplyLO6: Implement an IRCTC-style waitlist queue using LinkedList as a Queue with proper enqueue/dequeue operations
๐ŸŸ  AnalyzeLO7: Compare ArrayList vs LinkedList across 10 parameters and determine which is optimal for a given use case
๐ŸŸ  AnalyzeLO8: Analyze how HashSet internally uses HashMap and why it guarantees uniqueness
๐Ÿ”ด EvaluateLO9: Evaluate the trade-offs of using TreeMap vs HashMap vs LinkedHashMap for a Flipkart product catalog and justify the best choice
๐Ÿ”ด EvaluateLO10: Assess when to use Iterator vs ListIterator vs enhanced for-loop, considering ConcurrentModificationException risks
๐ŸŸฃ CreateLO11: Design and code a complete Flipkart Product Catalog system using HashMap with CRUD operations
๐ŸŸฃ CreateLO12: Build an LRU Cache using LinkedHashMap with access-order mode, suitable for interview-level demonstration
Section C

Concept Explanation โ€” Java Collections Framework from Scratch

1. The Collection Hierarchy

Think of Java Collections Framework like a well-organised Indian railway system. Just as railways have different types of trains (Express, Local, Rajdhani) for different needs, Collections has different interfaces and classes for different data storage needs.

๐Ÿ“Š The Collection Interface Hierarchy

Hierarchy
// Collection Hierarchy (Iterable โ†’ Collection โ†’ List/Set/Queue)

Iterable (root interface)
  โ””โ”€โ”€ Collection
        โ”œโ”€โ”€ List (ordered, allows duplicates)
        โ”‚     โ”œโ”€โ”€ ArrayList    โ€” dynamic array, O(1) random access
        โ”‚     โ”œโ”€โ”€ LinkedList   โ€” doubly-linked list, O(1) insert/delete
        โ”‚     โ””โ”€โ”€ Vector       โ€” synchronized (legacy, use ArrayList)
        โ”‚           โ””โ”€โ”€ Stack   โ€” LIFO (legacy, use ArrayDeque)
        โ”‚
        โ”œโ”€โ”€ Set (no duplicates)
        โ”‚     โ”œโ”€โ”€ HashSet      โ€” unordered, O(1) ops, uses HashMap
        โ”‚     โ”œโ”€โ”€ LinkedHashSetโ€” insertion-ordered, O(1) ops
        โ”‚     โ””โ”€โ”€ TreeSet      โ€” sorted, O(log n) ops, uses TreeMap
        โ”‚
        โ””โ”€โ”€ Queue (FIFO processing)
              โ”œโ”€โ”€ PriorityQueueโ€” min-heap, O(log n) insert/remove
              โ””โ”€โ”€ Deque (double-ended queue)
                    โ””โ”€โ”€ ArrayDeque โ€” resizable array, faster than Stack/LinkedList

// Map Hierarchy (separate from Collection)
Map (key-value pairs)
  โ”œโ”€โ”€ HashMap        โ€” unordered, O(1) ops, allows null key
  โ”œโ”€โ”€ LinkedHashMap  โ€” insertion/access ordered, O(1) ops
  โ”œโ”€โ”€ TreeMap        โ€” sorted by key, O(log n) ops
  โ””โ”€โ”€ Hashtable      โ€” synchronized (legacy, use ConcurrentHashMap)
HashMap = PhonePe contact list. Think about it: your PhonePe app maps a contact name (key) to a UPI ID (value). When you type "Mom", it instantly finds mom@ybl โ€” that's O(1) lookup, exactly like HashMap. Whether you have 5 contacts or 5,000, the lookup speed is constant.
Map does NOT extend Collection. This is the #1 conceptual mistake in exams. Map is a separate interface hierarchy. Map<K,V> stores key-value pairs, while Collection<E> stores single elements. Don't write "Map implements Collection" in your exam โ€” it's wrong!

2. ArrayList vs LinkedList โ€” The 10-Parameter Showdown

Analogy: ArrayList is like a movie theatre โ€” seats are numbered (indexed), you can jump to seat 42 instantly, but inserting a new seat in the middle means shifting everyone. LinkedList is like a train โ€” each coach is linked to the next, adding/removing a coach in the middle is easy, but finding coach #42 means walking from the engine.

#ParameterArrayListLinkedList
1Internal StructureDynamic resizable arrayDoubly-linked list (nodes)
2Random Access (get)O(1) โ€” direct indexO(n) โ€” must traverse
3Add at EndO(1) amortizedO(1)
4Add at MiddleO(n) โ€” shifts elementsO(1) โ€” pointer change (if position known)
5Remove at MiddleO(n) โ€” shifts elementsO(1) โ€” pointer change (if position known)
6Memory OverheadLower โ€” contiguous arrayHigher โ€” each node stores prev/next pointers
7Cache PerformanceExcellent โ€” locality of referencePoor โ€” nodes scattered in heap
8Implements Queue/Deque?โŒ Noโœ… Yes โ€” implements Deque
9Thread SafetyNot synchronizedNot synchronized
10Best Use CaseRead-heavy (90% of cases)Insert/delete-heavy, queue/deque needs
In 90% of real-world Java code, use ArrayList. Despite LinkedList's theoretical O(1) insertion advantage, ArrayList's cache-friendly contiguous memory layout makes it faster in practice for most operations. Even Joshua Bloch (creator of Java Collections) recommends ArrayList as the default choice.
Java
// ArrayList โ€” Flipkart Cart Example
import java.util.ArrayList;

public class FlipkartCart {
    public static void main(String[] args) {
        ArrayList<String> cart = new ArrayList<>();
        
        // Adding items to cart โ€” O(1) amortized
        cart.add("iPhone 16 Pro");        // index 0
        cart.add("Samsung Galaxy S24");    // index 1
        cart.add("OnePlus Nord 4");       // index 2
        cart.add("Boat Airdopes 441");    // index 3
        
        // Random access โ€” O(1)
        System.out.println("Item 2: " + cart.get(1)); // Samsung Galaxy S24
        
        // Remove item โ€” O(n) shifts remaining
        cart.remove("Samsung Galaxy S24");
        
        // Iterate cart
        System.out.println("=== Your Flipkart Cart ===");
        for (int i = 0; i < cart.size(); i++) {
            System.out.println((i+1) + ". " + cart.get(i));
        }
        System.out.println("Total items: " + cart.size());
    }
}
=== Your Flipkart Cart === 1. iPhone 16 Pro 2. OnePlus Nord 4 3. Boat Airdopes 441 Total items: 3

3. HashSet, TreeSet, LinkedHashSet โ€” No Duplicates Allowed

Analogy: Think of Set like Aadhaar numbers โ€” every Indian gets exactly ONE unique number. You can't have two people with the same Aadhaar. That's what Set does โ€” guarantees uniqueness.

Set TypeOrderPerformanceNull?Use Case
HashSetNo order guaranteedO(1) add/remove/contains1 nullFast uniqueness check โ€” "Has this email been registered?"
LinkedHashSetInsertion order preservedO(1) add/remove/contains1 nullUnique items where order matters โ€” recent search history
TreeSetSorted (natural/comparator)O(log n) all opsNo nullSorted unique data โ€” leaderboard scores, alphabetical names
Java
// HashSet โ€” Unique voter IDs at a booth
import java.util.*;

public class VoterBooth {
    public static void main(String[] args) {
        Set<String> voters = new HashSet<>();
        
        voters.add("VOTER001");
        voters.add("VOTER002");
        voters.add("VOTER003");
        voters.add("VOTER001");  // โŒ Duplicate โ€” silently ignored!
        
        System.out.println("Total unique voters: " + voters.size()); // 3
        System.out.println("VOTER001 voted? " + voters.contains("VOTER001")); // true
        
        // TreeSet โ€” sorted leaderboard
        TreeSet<Integer> scores = new TreeSet<>();
        scores.add(85); scores.add(92); scores.add(78); scores.add(95);
        System.out.println("Sorted scores: " + scores);    // [78, 85, 92, 95]
        System.out.println("Topper: " + scores.last());     // 95
        System.out.println("Lowest: " + scores.first());    // 78
    }
}
HashSet internally uses a HashMap! When you do hashSet.add("VOTER001"), it internally does hashMap.put("VOTER001", DUMMY_OBJECT). The keys are your Set elements, and all values point to the same dummy constant object PRESENT. This is why HashSet has O(1) performance โ€” it piggybacks on HashMap's hashing.

4. PriorityQueue & ArrayDeque

Analogy: PriorityQueue is like an emergency room (ER) at AIIMS Delhi โ€” patients aren't treated first-come-first-served. The most critical patient (highest priority) is treated first, regardless of arrival time. ArrayDeque is like a Mumbai local train door โ€” people can enter and exit from both ends.

Java
// PriorityQueue โ€” IRCTC Flash Deal Countdown
import java.util.*;

public class FlashDealCountdown {
    public static void main(String[] args) {
        // Min-heap: deal expiring soonest comes first
        PriorityQueue<String> dealQueue = new PriorityQueue<>(
            (a, b) -> {
                int minA = Integer.parseInt(a.split(":")[0]);
                int minB = Integer.parseInt(b.split(":")[0]);
                return minA - minB;
            }
        );
        
        dealQueue.add("5:iPhone 16 - โ‚น59,999");
        dealQueue.add("2:Boat Earbuds - โ‚น499");
        dealQueue.add("10:Samsung TV - โ‚น29,999");
        dealQueue.add("1:Mi Band - โ‚น999");
        
        System.out.println("=== Flash Deals (Expiring Soonest First) ===");
        while (!dealQueue.isEmpty()) {
            String deal = dealQueue.poll(); // removes and returns head
            System.out.println("โฐ Expiring in " + deal.split(":")[0] 
                + " min โ†’ " + deal.split(":")[1]);
        }
    }
}
=== Flash Deals (Expiring Soonest First) === โฐ Expiring in 1 min โ†’ Mi Band - โ‚น999 โฐ Expiring in 2 min โ†’ Boat Earbuds - โ‚น499 โฐ Expiring in 5 min โ†’ iPhone 16 - โ‚น59,999 โฐ Expiring in 10 min โ†’ Samsung TV - โ‚น29,999
Java
// ArrayDeque โ€” Faster than Stack and LinkedList
import java.util.*;

public class BrowserHistory {
    public static void main(String[] args) {
        // Use ArrayDeque as Stack (LIFO)
        Deque<String> history = new ArrayDeque<>();
        
        history.push("flipkart.com");
        history.push("flipkart.com/mobiles");
        history.push("flipkart.com/iphone-16");
        
        System.out.println("Current page: " + history.peek());  // iphone-16
        history.pop();  // Go back
        System.out.println("After back: " + history.peek());   // /mobiles
    }
}

5. HashMap โ€” Internal Working (Interview Favourite)

Plain English: Imagine a library with 16 shelves (buckets). When you bring a new book, the librarian runs the book title through a formula (hash function) that produces a shelf number. The book goes on that shelf. When you ask for it later, same formula โ†’ same shelf โ†’ instant retrieval.

๐Ÿ”ง HashMap Internals โ€” How It Really Works

Step 1 โ€” Hashing: When you do map.put("iPhone", 59999), Java calls "iPhone".hashCode() which returns an integer (e.g., -2077747470). This is then compressed: index = hash & (n-1) where n = number of buckets (default 16).

Step 2 โ€” Bucket Storage: The computed index (0โ€“15) determines which bucket the entry goes into. Each bucket is initially a linked list of Node<K,V> objects.

Step 3 โ€” Collision Handling: If two keys hash to the same bucket (collision), the new entry is appended to the linked list in that bucket. This is called chaining.

Step 4 โ€” Treeification (Java 8+): When a single bucket's linked list grows beyond 8 nodes (TREEIFY_THRESHOLD), it converts to a balanced Red-Black Tree, improving worst-case from O(n) to O(log n).

Step 5 โ€” Resizing: When total entries exceed capacity ร— loadFactor (default: 16 ร— 0.75 = 12), HashMap doubles its bucket array to 32 and rehashes all entries.

Internals
// HashMap Internal Structure (Java 8+)

Bucket Array (Node<K,V>[])
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ [0] โ†’ null                                    โ”‚
โ”‚ [1] โ†’ Node("Milk",40) โ†’ null                 โ”‚
โ”‚ [2] โ†’ null                                    โ”‚
โ”‚ [3] โ†’ Node("Rice",60) โ†’ Node("Dal",80) โ†’ nullโ”‚  โ† collision chain
โ”‚ [4] โ†’ null                                    โ”‚
โ”‚ ...                                           โ”‚
โ”‚ [7] โ†’ ๐ŸŒณ Red-Black Tree (if > 8 nodes)       โ”‚  โ† treeified bucket
โ”‚ ...                                           โ”‚
โ”‚[15] โ†’ Node("Bread",35) โ†’ null                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Default capacity: 16 buckets
Load factor: 0.75 (resize when 75% full)
TREEIFY_THRESHOLD: 8 (linked list โ†’ tree)
Interview favourite: "What happens when two keys have the same hashCode?" Answer: Both go to the same bucket. put() traverses the linked list/tree in that bucket, comparing keys with .equals(). If a matching key is found, the value is updated. If not, a new Node is appended. This is why you MUST override both hashCode() AND equals() when using custom objects as keys.
Java
// Full Code: FlipkartCatalog using HashMap
import java.util.*;

public class FlipkartCatalog {
    static HashMap<String, Double> catalog = new HashMap<>();
    static Scanner sc = new Scanner(System.in);
    
    public static void main(String[] args) {
        // Pre-load catalog
        catalog.put("PROD001", 59999.0);  // iPhone 16
        catalog.put("PROD002", 24999.0);  // Samsung Galaxy M34
        catalog.put("PROD003", 1499.0);   // Boat Rockerz 450
        catalog.put("PROD004", 34999.0);  // HP Laptop 15s
        catalog.put("PROD005", 999.0);    // Mi Band 8
        
        int choice;
        do {
            System.out.println("\n=== Flipkart Product Catalog ===");
            System.out.println("1. Add Product");
            System.out.println("2. Search Product by ID");
            System.out.println("3. Update Price");
            System.out.println("4. Remove Product");
            System.out.println("5. Display All Products");
            System.out.println("6. Exit");
            System.out.print("Choice: ");
            choice = sc.nextInt();
            sc.nextLine();
            
            switch (choice) {
                case 1: addProduct(); break;
                case 2: searchProduct(); break;
                case 3: updatePrice(); break;
                case 4: removeProduct(); break;
                case 5: displayAll(); break;
            }
        } while (choice != 6);
    }
    
    static void addProduct() {
        System.out.print("Product ID: ");
        String id = sc.nextLine();
        System.out.print("Price (โ‚น): ");
        double price = sc.nextDouble();
        catalog.put(id, price); // O(1)
        System.out.println("โœ… Product added!");
    }
    
    static void searchProduct() {
        System.out.print("Enter Product ID: ");
        String id = sc.nextLine();
        if (catalog.containsKey(id)) {  // O(1)
            System.out.println("โœ… Found! Price: โ‚น" + catalog.get(id));
        } else {
            System.out.println("โŒ Product not found.");
        }
    }
    
    static void updatePrice() {
        System.out.print("Product ID: ");
        String id = sc.nextLine();
        if (catalog.containsKey(id)) {
            System.out.print("New price (โ‚น): ");
            catalog.put(id, sc.nextDouble()); // O(1) โ€” replaces old value
            System.out.println("โœ… Price updated!");
        } else {
            System.out.println("โŒ Product not found.");
        }
    }
    
    static void removeProduct() {
        System.out.print("Product ID: ");
        String id = sc.nextLine();
        if (catalog.remove(id) != null) { // O(1)
            System.out.println("โœ… Product removed.");
        } else {
            System.out.println("โŒ Product not found.");
        }
    }
    
    static void displayAll() {
        System.out.println("\n--- All Products ---");
        for (Map.Entry<String, Double> entry : catalog.entrySet()) {
            System.out.printf("%-10s โ†’ โ‚น%,.0f%n", entry.getKey(), entry.getValue());
        }
        System.out.println("Total products: " + catalog.size());
    }
}

6. TreeMap & LinkedHashMap

FeatureHashMapTreeMapLinkedHashMap
OrderNo orderSorted by key (natural/comparator)Insertion order (or access order)
PerformanceO(1) avgO(log n) โ€” Red-Black TreeO(1) avg
Null key?โœ… 1 null keyโŒ No null keyโœ… 1 null key
Internal StructureArray + Linked List/TreeRed-Black TreeHashMap + Doubly-Linked List
Best ForGeneral purposeRange queries, sorted keysLRU Cache, ordered iteration
Java
// TreeMap โ€” Student marks sorted by name
import java.util.*;

public class SortedStudentMarks {
    public static void main(String[] args) {
        TreeMap<String, Integer> marks = new TreeMap<>();
        marks.put("Aarav", 92);
        marks.put("Zara", 88);
        marks.put("Kishore", 95);
        marks.put("Diya", 91);
        marks.put("Meena", 87);
        
        System.out.println("Alphabetical order: " + marks);
        System.out.println("First (A): " + marks.firstKey());    // Aarav
        System.out.println("Last (Z): " + marks.lastKey());     // Zara
        System.out.println("D-M range: " + marks.subMap("D", "N")); // Diya, Kishore, Meena
    }
}

7. Collections Utility Class

The Collections class (note the 's' โ€” it's different from Collection interface) provides static utility methods for operating on collections:

Java
import java.util.*;

public class CollectionsDemo {
    public static void main(String[] args) {
        List<Integer> marks = new ArrayList<>(Arrays.asList(78, 92, 45, 88, 65));
        
        Collections.sort(marks);           // [45, 65, 78, 88, 92]
        Collections.reverse(marks);        // [92, 88, 78, 65, 45]
        Collections.shuffle(marks);        // random order
        
        System.out.println("Max: " + Collections.max(marks));  // 92
        System.out.println("Min: " + Collections.min(marks));  // 45
        System.out.println("Freq of 78: " + Collections.frequency(marks, 78));
        
        // Unmodifiable collection โ€” immutable wrapper
        List<String> states = Collections.unmodifiableList(
            Arrays.asList("Maharashtra", "Karnataka", "Tamil Nadu")
        );
        // states.add("Kerala"); โ† throws UnsupportedOperationException!
    }
}

8. Iterator & ListIterator

FeatureIteratorListIteratorEnhanced for-loop
DirectionForward onlyForward + BackwardForward only
Remove during iteration?โœ… Yes โ€” it.remove()โœ… YesโŒ No โ€” ConcurrentModificationException
Add during iteration?โŒ Noโœ… Yes โ€” it.add()โŒ No
Works withAll CollectionsList onlyAll Iterable
Get index?โŒ Noโœ… Yes โ€” nextIndex()โŒ No
Java
// Safe removal during iteration โ€” Iterator
import java.util.*;

public class SafeRemoval {
    public static void main(String[] args) {
        List<Integer> marks = new ArrayList<>(Arrays.asList(85, 32, 91, 28, 76, 44));
        
        // โŒ WRONG: ConcurrentModificationException
        // for (int m : marks) { if (m < 40) marks.remove(Integer.valueOf(m)); }
        
        // โœ… CORRECT: Use Iterator
        Iterator<Integer> it = marks.iterator();
        while (it.hasNext()) {
            if (it.next() < 40) {
                it.remove();  // Safe removal!
            }
        }
        System.out.println("Passing marks: " + marks); // [85, 91, 76, 44]
    }
}
Never modify a Collection inside a for-each loop! This is the most common bug in Java. Using list.remove() inside for (Type x : list) throws ConcurrentModificationException. Always use Iterator.remove() or list.removeIf() (Java 8+) instead.

9. Comparable vs Comparator

FeatureComparableComparator
Packagejava.langjava.util
MethodcompareTo(T o)compare(T o1, T o2)
Modifies class?Yes โ€” class must implement itNo โ€” external, separate class/lambda
Sorting countSingle natural orderingMultiple custom orderings
UsageCollections.sort(list)Collections.sort(list, comparator)
AnalogyDefault sort = Alphabetical roll callCustom sort = Sort by marks, attendance, etc.
Java
// Full Code: StudentResultSystem โ€” Comparable + Comparator
import java.util.*;

class Student implements Comparable<Student> {
    String name;
    int rollNo;
    double percentage;
    
    Student(String name, int rollNo, double percentage) {
        this.name = name;
        this.rollNo = rollNo;
        this.percentage = percentage;
    }
    
    // Natural ordering: by roll number
    public int compareTo(Student other) {
        return this.rollNo - other.rollNo;
    }
    
    public String toString() {
        return String.format("Roll#%d %-12s %.1f%%", rollNo, name, percentage);
    }
}

public class StudentResultSystem {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Aarav Patel", 103, 87.5));
        students.add(new Student("Sneha Iyer", 101, 92.3));
        students.add(new Student("Rohit Kumar", 105, 78.9));
        students.add(new Student("Diya Sharma", 102, 95.1));
        students.add(new Student("Kishore Nair", 104, 88.7));
        
        // Sort by roll number (Comparable โ€” natural order)
        Collections.sort(students);
        System.out.println("=== Sorted by Roll Number (Comparable) ===");
        students.forEach(System.out::println);
        
        // Sort by percentage descending (Comparator โ€” custom order)
        students.sort((s1, s2) -> Double.compare(s2.percentage, s1.percentage));
        System.out.println("\n=== Sorted by Percentage Descending (Comparator) ===");
        students.forEach(System.out::println);
        
        // Sort by name alphabetically (Comparator)
        students.sort(Comparator.comparing(s -> s.name));
        System.out.println("\n=== Sorted by Name (Comparator) ===");
        students.forEach(System.out::println);
        
        // Store in HashMap for O(1) lookup by roll number
        HashMap<Integer, Student> studentMap = new HashMap<>();
        for (Student s : students) {
            studentMap.put(s.rollNo, s);
        }
        
        // Instant lookup
        System.out.println("\n๐Ÿ” Lookup Roll#103: " + studentMap.get(103));
    }
}
=== Sorted by Roll Number (Comparable) === Roll#101 Sneha Iyer 92.3% Roll#102 Diya Sharma 95.1% Roll#103 Aarav Patel 87.5% Roll#104 Kishore Nair 88.7% Roll#105 Rohit Kumar 78.9% === Sorted by Percentage Descending (Comparator) === Roll#102 Diya Sharma 95.1% Roll#101 Sneha Iyer 92.3% Roll#104 Kishore Nair 88.7% Roll#103 Aarav Patel 87.5% Roll#105 Rohit Kumar 78.9% === Sorted by Name (Comparator) === Roll#103 Aarav Patel 87.5% Roll#102 Diya Sharma 95.1% Roll#104 Kishore Nair 88.7% Roll#105 Rohit Kumar 78.9% Roll#101 Sneha Iyer 92.3% ๐Ÿ” Lookup Roll#103: Roll#103 Aarav Patel 87.5%

10. Full Code: IRCTC Waitlist System

Java
// IRCTC Waitlist System using LinkedList as Queue
import java.util.*;

class Passenger {
    String pnr, name;
    int age;
    String status; // CONFIRMED, WAITLIST, RAC
    
    Passenger(String pnr, String name, int age) {
        this.pnr = pnr;
        this.name = name;
        this.age = age;
        this.status = "WAITLIST";
    }
    
    public String toString() {
        return String.format("PNR: %s | %-15s | Age: %d | Status: %s", 
            pnr, name, age, status);
    }
}

public class IRCTCWaitlist {
    static final int MAX_CONFIRMED = 5;
    static List<Passenger> confirmed = new ArrayList<>();
    static Queue<Passenger> waitlist = new LinkedList<>();
    static Map<String, Passenger> pnrMap = new HashMap<>();
    static int pnrCounter = 1000;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int choice;
        
        do {
            System.out.println("\n๐Ÿš‚ === IRCTC Booking System ===");
            System.out.println("1. Book Ticket");
            System.out.println("2. Cancel Ticket (by PNR)");
            System.out.println("3. Check PNR Status");
            System.out.println("4. View All Passengers");
            System.out.println("5. Exit");
            System.out.print("Choice: ");
            choice = sc.nextInt(); sc.nextLine();
            
            switch (choice) {
                case 1:
                    System.out.print("Name: ");
                    String name = sc.nextLine();
                    System.out.print("Age: ");
                    int age = sc.nextInt();
                    bookTicket(name, age);
                    break;
                case 2:
                    System.out.print("Enter PNR: ");
                    cancelTicket(sc.nextLine());
                    break;
                case 3:
                    System.out.print("Enter PNR: ");
                    checkPNR(sc.nextLine());
                    break;
                case 4:
                    viewAll();
                    break;
            }
        } while (choice != 5);
        System.out.println("๐Ÿ™ Thank you for using IRCTC!");
    }
    
    static void bookTicket(String name, int age) {
        String pnr = "PNR" + (++pnrCounter);
        Passenger p = new Passenger(pnr, name, age);
        
        if (confirmed.size() < MAX_CONFIRMED) {
            p.status = "CONFIRMED";
            confirmed.add(p);
            System.out.println("โœ… CONFIRMED! PNR: " + pnr);
        } else {
            p.status = "WL/" + (waitlist.size() + 1);
            waitlist.add(p);  // enqueue at end
            System.out.println("โณ WAITLISTED (" + p.status + ") PNR: " + pnr);
        }
        pnrMap.put(pnr, p); // O(1) lookup later
    }
    
    static void cancelTicket(String pnr) {
        Passenger p = pnrMap.get(pnr);
        if (p == null) { System.out.println("โŒ PNR not found."); return; }
        
        if (p.status.equals("CONFIRMED")) {
            confirmed.remove(p);
            // Promote first waitlisted passenger
            if (!waitlist.isEmpty()) {
                Passenger promoted = waitlist.poll(); // dequeue from front
                promoted.status = "CONFIRMED";
                confirmed.add(promoted);
                System.out.println("๐ŸŽ‰ " + promoted.name + " promoted to CONFIRMED!");
            }
        } else {
            waitlist.remove(p);
        }
        pnrMap.remove(pnr);
        System.out.println("โœ… Ticket " + pnr + " cancelled.");
    }
    
    static void checkPNR(String pnr) {
        Passenger p = pnrMap.get(pnr); // O(1)
        System.out.println(p != null ? p : "โŒ PNR not found.");
    }
    
    static void viewAll() {
        System.out.println("\n--- Confirmed (" + confirmed.size() + "/" + MAX_CONFIRMED + ") ---");
        confirmed.forEach(System.out::println);
        System.out.println("--- Waitlist (" + waitlist.size() + ") ---");
        waitlist.forEach(System.out::println);
    }
}
Section D

Learn by Doing โ€” 3-Tier Lab: Student Result Management System

๐ŸŸข Tier 1 โ€” GUIDED: Student Result System with ArrayList & HashMap

โฑ๏ธ 60โ€“90 minutesBeginnerStep-by-step guided

Step 1: Create the Student class

Create a class Student with fields: rollNo (int), name (String), marks (int[5] for 5 subjects). Implement Comparable<Student> to sort by rollNo.

Step 2: Build the Management System

Use ArrayList<Student> to store all students and HashMap<Integer, Student> for O(1) lookup by roll number. Implement: Add, Search, Display All, Sort by Marks.

Step 3: Add Menu-Driven Interface

Use a do-while loop with Scanner for menu: 1) Add Student, 2) Search by Roll No, 3) Display All, 4) Sort by Percentage, 5) Top 3 Students, 6) Exit.

Step 4: Test with 5+ students

Add at least 5 Indian student names, sort by percentage, and find the topper.

Expected Output:

=== Student Result Management System === 1. Add Student 2. Search by Roll No 3. Display All (sorted by Roll No) 4. Sort by Percentage (descending) 5. Show Top 3 Students 6. Exit Choice: 4 --- Students by Percentage --- Roll#102 Diya Sharma 95.1% [DISTINCTION] Roll#101 Sneha Iyer 92.3% [DISTINCTION] Roll#104 Kishore Nair 88.7% [FIRST CLASS] Roll#103 Aarav Patel 87.5% [FIRST CLASS] Roll#105 Rohit Kumar 78.9% [FIRST CLASS]

๐ŸŸก Tier 2 โ€” SEMI-GUIDED: Add Subject-Wise Analytics

โฑ๏ธ 90 minutesIntermediateHints provided

Your Mission:

Extend the Tier 1 system with: subject-wise highest/lowest using TreeMap<String, TreeSet<Integer>>, pass/fail filter using Iterator (remove failed students into a separate list), and class average calculation.

Hints:

  1. Use TreeMap<String, TreeSet<Integer>> where key = subject name, value = sorted set of marks
  2. Use Iterator to safely remove students with percentage < 40% into a failedStudents list
  3. Use Collections.max() and Collections.min() for class topper/weakest
Stretch Goal: Add a Comparator to sort students by individual subject marks. E.g., "Show students sorted by Maths marks descending."

๐Ÿ”ด Tier 3 โ€” OPEN CHALLENGE: Full Flipkart Inventory System

โฑ๏ธ 2โ€“3 hoursAdvancedNo instructions โ€” real-world project

The Brief:

Build a complete e-commerce inventory system with:

  1. Product Catalog: HashMap<String, Product> โ€” CRUD operations with product ID as key
  2. Category Index: TreeMap<String, List<Product>> โ€” products grouped and sorted by category
  3. Cart: ArrayList<Product> with add/remove/total calculation
  4. Order Queue: PriorityQueue โ€” orders prioritised by order amount (highest first)
  5. Unique Customers: HashSet<Customer> โ€” no duplicate registrations
  6. Search History: LinkedHashSet<String> โ€” recent searches in order

Deliverable: A single Java file with all classes, menu-driven, with at least 10 pre-loaded products.

Section E

Problem Set

Syntax-Level Questions (5)

  1. Write the syntax to create an ArrayList of Strings, add 3 elements, and print the element at index 1.
  2. Write code to create a HashMap<String, Integer>, insert 3 key-value pairs, and retrieve a value by key.
  3. Write the syntax to iterate over a HashSet<String> using an Iterator and print each element.
  4. Write code to sort an ArrayList<Integer> in descending order using Collections.sort() with a Comparator.
  5. Write the syntax to create a PriorityQueue<Integer> (max-heap) and add 5 elements.

Programming Questions (8)

  1. Write a program that takes 10 names as input, stores them in an ArrayList, and displays them sorted alphabetically using Collections.sort().
  2. Write a program that counts the frequency of each word in a paragraph using HashMap<String, Integer>.
  3. Write a program to remove all duplicate elements from an ArrayList using a HashSet.
  4. Implement a phone book using TreeMap<String, String> (name โ†’ phone number) that displays contacts in alphabetical order with search functionality.
  5. Write a program to find the first non-repeating character in a string using LinkedHashMap.
  6. Implement a todo list using LinkedList with operations: addTask, removeTask, markComplete, displayPending.
  7. Write a program that merges two sorted ArrayLists into a single sorted ArrayList without using Collections.sort().
  8. Create a program that reads student names and marks from input, stores them in a HashMap, and prints students who scored above average.

Industry-Level Problems (3) โ€” IRCTC Waitlist Theme

๐Ÿš‚ Industry Problem 1: IRCTC Tatkal Queue Simulator

Simulate IRCTC's Tatkal booking: 100 passengers try to book 20 seats. Use PriorityQueue to prioritise by booking time (earlier = higher priority). If seats full, add to waitlist (Queue). When a confirmed passenger cancels, auto-promote from waitlist. Track using HashMap<PNR, Passenger>.

๐Ÿš‚ Industry Problem 2: Train Route Station Tracker

Use LinkedHashMap<String, Integer> (station name โ†’ distance from origin) to model the Delhi โ†’ Chennai Rajdhani route. Support: display all stations in order, find distance between any two stations, list stations in a given range. Hint: Insertion order of LinkedHashMap preserves the station sequence.

๐Ÿš‚ Industry Problem 3: Duplicate Ticket Detection

Given a list of 1000 booking entries (name + date + train), use HashSet to detect duplicate bookings (same person booking same train on same date). Report all duplicates with count using HashMap<String, Integer>.

Interview-Level Problems (3) โ€” LRU Cache Theme

๐Ÿ’ผ Interview Problem 1: LRU Cache using LinkedHashMap

Problem: Design an LRU (Least Recently Used) Cache of capacity K. Support get(key) and put(key, value) in O(1). When cache is full, evict the least recently used entry.

Hint: Use LinkedHashMap with accessOrder = true and override removeEldestEntry().

Java
import java.util.*;

class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int capacity;
    
    public LRUCache(int capacity) {
        super(capacity, 0.75f, true); // accessOrder = true!
        this.capacity = capacity;
    }
    
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity; // evict when over capacity
    }
    
    public static void main(String[] args) {
        LRUCache<String, String> cache = new LRUCache<>(3);
        
        cache.put("user1", "Aarav");
        cache.put("user2", "Sneha");
        cache.put("user3", "Kishore");
        System.out.println(cache); // {user1=Aarav, user2=Sneha, user3=Kishore}
        
        cache.get("user1");  // Access user1 โ€” moves to end
        cache.put("user4", "Diya");  // Capacity exceeded โ€” user2 evicted (LRU)
        
        System.out.println(cache); // {user3=Kishore, user1=Aarav, user4=Diya}
        // user2 was evicted because it was least recently used!
    }
}

๐Ÿ’ผ Interview Problem 2: Top K Frequent Elements

Given an array [1,1,1,2,2,3] and k=2, return the 2 most frequent elements. Use HashMap for frequency count + PriorityQueue (min-heap of size k) for top-k selection. Expected: [1, 2].

๐Ÿ’ผ Interview Problem 3: Group Anagrams

Given ["eat","tea","tan","ate","nat","bat"], group anagrams together. Use HashMap<String, List<String>> where key = sorted characters. Expected: [[eat,tea,ate], [tan,nat], [bat]].

Section F

MCQ Assessment Bank โ€” 30 Questions (Bloom's Mapped)

Remember / Identify (Q1โ€“Q5)

Q1

Which interface is the root of the Collection hierarchy in Java?

  1. Collection
  2. Iterable
  3. List
  4. Object
Remember
โœ… Answer: (B) Iterable โ€” The hierarchy is Iterable โ†’ Collection โ†’ List/Set/Queue. Iterable defines the iterator() method that enables for-each loops.
Q2

Which Collection class uses a doubly-linked list internally?

  1. ArrayList
  2. HashSet
  3. LinkedList
  4. TreeSet
Remember
โœ… Answer: (C) LinkedList โ€” It maintains a doubly-linked list of nodes, where each node has references to both the previous and next node.
Q3

What is the default initial capacity of a HashMap in Java?

  1. 8
  2. 16
  3. 32
  4. 10
Remember
โœ… Answer: (B) 16 โ€” HashMap starts with 16 buckets and a load factor of 0.75. It resizes (doubles) when entries exceed 16 ร— 0.75 = 12.
Q4

Which Map implementation maintains keys in sorted order?

  1. HashMap
  2. LinkedHashMap
  3. TreeMap
  4. Hashtable
Remember
โœ… Answer: (C) TreeMap โ€” It uses a Red-Black Tree internally and stores entries sorted by key (natural order or Comparator).
Q5

PriorityQueue in Java implements which data structure by default?

  1. Max-heap
  2. Min-heap
  3. Binary Search Tree
  4. Stack
Remember
โœ… Answer: (B) Min-heap โ€” By default, PriorityQueue orders elements in natural ascending order (smallest first). Use a custom Comparator for max-heap behavior.

Understand / Explain (Q6โ€“Q10)

Q6

Why does HashSet not allow duplicate elements?

  1. It uses an array that checks every element linearly
  2. It internally uses a HashMap where elements are stored as keys, and keys must be unique
  3. It throws an exception when duplicates are added
  4. It uses a TreeMap for uniqueness checks
Understand
โœ… Answer: (B) โ€” HashSet is backed by a HashMap. When you add an element, it becomes a key in the HashMap. Since Map keys must be unique, duplicates are automatically rejected (add() returns false).
Q7

What happens when a HashMap bucket's linked list exceeds 8 nodes (Java 8+)?

  1. The HashMap throws an OverflowException
  2. The linked list converts to a Red-Black Tree for O(log n) search
  3. The HashMap doubles its capacity
  4. The extra nodes are discarded
Understand
โœ… Answer: (B) โ€” When TREEIFY_THRESHOLD (8) is exceeded, the bucket's linked list is converted to a balanced Red-Black Tree, improving worst-case lookup from O(n) to O(log n). This was a Java 8 performance improvement.
Q8

Why is ArrayList faster than LinkedList for random access (get by index)?

  1. ArrayList uses hashing
  2. ArrayList stores elements in contiguous memory, allowing direct index calculation
  3. LinkedList doesn't support indexing
  4. ArrayList is synchronized
Understand
โœ… Answer: (B) โ€” ArrayList uses a contiguous array internally. get(i) directly accesses elementData[i] in O(1). LinkedList must traverse node-by-node from head, making it O(n).
Q9

What is the difference between Comparable and Comparator?

  1. Comparable is faster than Comparator
  2. Comparable defines natural ordering inside the class; Comparator defines custom ordering externally
  3. Comparator can only sort in ascending order
  4. Comparable is in java.util; Comparator is in java.lang
Understand
โœ… Answer: (B) โ€” Comparable (java.lang) uses compareTo() inside the class for ONE natural order. Comparator (java.util) uses compare() externally, allowing MULTIPLE custom orderings without modifying the class.
Q10

Why does modifying a collection inside a for-each loop throw ConcurrentModificationException?

  1. The JVM doesn't support concurrent operations
  2. The for-each loop uses an Iterator internally, and structural modifications invalidate the Iterator's state
  3. The collection becomes read-only during iteration
  4. for-each loops don't support remove operations
Understand
โœ… Answer: (B) โ€” The for-each loop creates an Iterator behind the scenes. When you call list.remove() directly, it changes the collection's modCount without updating the Iterator's expectedModCount, causing the fail-fast mechanism to throw ConcurrentModificationException.

Apply (Q11โ€“Q15)

Q11

What is the output of this code?
ArrayList<String> list = new ArrayList<>(Arrays.asList("A","B","C")); list.add(1,"X"); System.out.println(list);

  1. [A, B, C, X]
  2. [X, A, B, C]
  3. [A, X, B, C]
  4. Compilation error
Apply
โœ… Answer: (C) [A, X, B, C] โ€” add(1, "X") inserts "X" at index 1, shifting B and C right. The original A at index 0 stays.
Q12

What is the output?
HashSet<Integer> set = new HashSet<>(); set.add(10); set.add(20); set.add(10); System.out.println(set.size());

  1. 3
  2. 2
  3. 1
  4. Compilation error
Apply
โœ… Answer: (B) 2 โ€” HashSet ignores duplicate additions. 10 is added once, 20 is added once. The second add(10) returns false and doesn't change the set.
Q13

What does Collections.unmodifiableList(list) return?

  1. A new sorted list
  2. A read-only wrapper that throws UnsupportedOperationException on modification
  3. A synchronized version of the list
  4. A copy of the list
Apply
โœ… Answer: (B) โ€” It returns an unmodifiable view. Any attempt to call add(), remove(), or set() on it throws UnsupportedOperationException. The original list can still be modified.
Q14

What is the output?
TreeSet<Integer> ts = new TreeSet<>(); ts.add(30); ts.add(10); ts.add(20); System.out.println(ts);

  1. [30, 10, 20]
  2. [10, 20, 30]
  3. [20, 10, 30]
  4. Exception at runtime
Apply
โœ… Answer: (B) [10, 20, 30] โ€” TreeSet maintains elements in sorted (natural) order using a Red-Black Tree. Insertion order is irrelevant.
Q15

What is the output?
HashMap<String,Integer> map = new HashMap<>(); map.put("A",1); map.put("B",2); map.put("A",3); System.out.println(map.get("A"));

  1. 1
  2. 3
  3. null
  4. Compilation error
Apply
โœ… Answer: (B) 3 โ€” When you put a key that already exists in HashMap, the value is replaced. The second put("A",3) overwrites the previous value 1 with 3.

Analyze (Q16โ€“Q20)

Q16

For an application that needs to frequently check if an element exists in a large dataset (1 million items), which collection is most efficient?

  1. ArrayList
  2. LinkedList
  3. HashSet
  4. TreeSet
Analyze
โœ… Answer: (C) HashSet โ€” contains() is O(1) average for HashSet vs O(n) for ArrayList/LinkedList and O(log n) for TreeSet. For 1 million items, HashSet is the clear winner.
Q17

An IRCTC system needs a queue where passengers are served by booking time, but senior citizens get priority. Which collection is best?

  1. ArrayDeque
  2. LinkedList
  3. PriorityQueue with custom Comparator
  4. ArrayList
Analyze
โœ… Answer: (C) PriorityQueue with custom Comparator โ€” The Comparator can prioritise senior citizens (age โ‰ฅ 60) first, then by booking time. PriorityQueue handles the heap ordering automatically.
Q18

A developer stores Student objects in a HashSet but finds duplicates appearing. What is the most likely cause?

  1. HashSet has a bug
  2. The Student class has not overridden hashCode() and equals()
  3. HashSet doesn't check for duplicates
  4. The JVM version is too old
Analyze
โœ… Answer: (B) โ€” HashSet uses hashCode() to find the bucket and equals() to check if the object already exists. Without proper overrides, two Student objects with the same data will have different hashCodes (inherited from Object), so HashSet treats them as different.
Q19

Which is true about the load factor of a HashMap?

  1. Higher load factor = more memory, fewer collisions
  2. Lower load factor = more memory, fewer collisions
  3. Load factor doesn't affect performance
  4. Default load factor is 1.0
Analyze
โœ… Answer: (B) โ€” Lower load factor (e.g., 0.5) means HashMap resizes sooner, resulting in more buckets (memory) but fewer collisions (speed). Default is 0.75, which balances memory and performance. Higher load factor saves memory but increases collisions.
Q20

In what scenario would LinkedList outperform ArrayList?

  1. Random access by index in a list of 10,000 elements
  2. Frequent insertions and deletions at the beginning of the list
  3. Sorting the list using Collections.sort()
  4. Iterating through all elements sequentially
Analyze
โœ… Answer: (B) โ€” Adding/removing at index 0 is O(1) for LinkedList (pointer change) but O(n) for ArrayList (must shift all elements). This is LinkedList's main practical advantage.

Evaluate (Q21โ€“Q25)

Q21

A Flipkart engineer needs to display recently viewed products in the order they were viewed, with no duplicates. Which collection is best?

  1. ArrayList
  2. HashSet
  3. LinkedHashSet
  4. TreeSet
Evaluate
โœ… Answer: (C) LinkedHashSet โ€” It maintains insertion order (preserving view sequence) while preventing duplicates. HashSet loses order; TreeSet sorts alphabetically; ArrayList allows duplicates.
Q22

Which statement about Java's legacy collections is correct?

  1. Vector and Hashtable should be used in modern code for thread safety
  2. Stack should be replaced with ArrayDeque for LIFO operations
  3. Hashtable is faster than HashMap because it's synchronized
  4. Vector is preferred over ArrayList for single-threaded applications
Evaluate
โœ… Answer: (B) โ€” Java documentation recommends ArrayDeque over Stack for LIFO operations. Vector and Hashtable's synchronization overhead makes them slower than ArrayList/HashMap in single-threaded scenarios. For thread-safety, use ConcurrentHashMap or Collections.synchronizedList().
Q23

For building an autocomplete feature (like Google search suggestions), which collection would you recommend?

  1. HashMap
  2. TreeMap
  3. ArrayList
  4. HashSet
Evaluate
โœ… Answer: (B) TreeMap โ€” Its subMap() and headMap() methods efficiently retrieve all entries starting with a given prefix (e.g., all words starting with "Jav"). HashMap doesn't support range queries; ArrayList would need linear scan.
Q24

A system processes 10 million records and needs to find the top 100 highest-valued items. Which approach is most memory-efficient?

  1. Sort entire list with Collections.sort() and take first 100
  2. Use a PriorityQueue (min-heap) of size 100
  3. Store all in TreeSet and iterate
  4. Use HashMap and scan all values
Evaluate
โœ… Answer: (B) โ€” A min-heap of size 100 uses O(100) memory regardless of input size. For each new element, compare with the heap's minimum: if larger, remove min and insert new. This gives O(n log k) time and O(k) space. Sorting the entire list uses O(n log n) time and O(n) space.
Q25

Which is NOT a valid way to make a HashMap thread-safe?

  1. Collections.synchronizedMap(hashMap)
  2. ConcurrentHashMap
  3. Using synchronized blocks around HashMap operations
  4. Setting the load factor to 0
Evaluate
โœ… Answer: (D) โ€” Load factor controls resize threshold, not thread safety. Options A, B, and C are all valid approaches to achieve thread-safe HashMap behavior. ConcurrentHashMap is the most performant for concurrent access.

Create (Q26โ€“Q30)

Q26

To implement an LRU (Least Recently Used) Cache with O(1) get and put, which combination is ideal?

  1. ArrayList + HashMap
  2. LinkedHashMap with accessOrder=true
  3. TreeMap + LinkedList
  4. HashSet + ArrayDeque
Create
โœ… Answer: (B) โ€” LinkedHashMap with accessOrder=true automatically moves accessed entries to the end. Override removeEldestEntry() to auto-evict the oldest entry when size exceeds capacity. Both get() and put() remain O(1).
Q27

You need to design a Flipkart product search that returns results sorted by price within each category. Which collection combination is best?

  1. HashMap<String, ArrayList<Product>>
  2. TreeMap<String, TreeSet<Product>> with Comparator
  3. LinkedHashMap<String, HashSet<Product>>
  4. ArrayList<Product> with Collections.sort()
Create
โœ… Answer: (B) TreeMap<String, TreeSet<Product>> โ€” TreeMap keeps categories sorted alphabetically. TreeSet with a price Comparator keeps products sorted by price within each category. Both maintain order automatically on insertion.
Q28

Which code correctly removes all elements less than 40 from an ArrayList during iteration?

  1. for(int x:list) if(x<40) list.remove(x);
  2. list.removeIf(x -> x < 40);
  3. for(int i=0;i<list.size();i++) list.remove(list.get(i));
  4. list.forEach(x -> list.remove(x));
Create
โœ… Answer: (B) โ€” removeIf() (Java 8+) is the cleanest and safest way. Option A throws ConcurrentModificationException. Option C has index-shifting bugs. Option D also throws ConcurrentModificationException.
Q29

To implement a frequency counter that also maintains insertion order of first occurrences, which Map should you use?

  1. HashMap
  2. TreeMap
  3. LinkedHashMap
  4. Hashtable
Create
โœ… Answer: (C) LinkedHashMap โ€” It maintains insertion order while providing O(1) operations. When iterating, elements appear in the order they were first inserted. HashMap would give correct counts but random iteration order.
Q30

Which design best implements a task scheduler where the highest-priority task runs first, with O(log n) insertion and O(log n) removal?

  1. ArrayList sorted after every insertion
  2. TreeSet with custom Comparator
  3. PriorityQueue with custom Comparator
  4. LinkedList with insertion sort
Create
โœ… Answer: (C) PriorityQueue โ€” It's a binary heap giving O(log n) for both offer() and poll(). TreeSet also works but uses more memory (Red-Black Tree nodes). ArrayList sorted on every insert is O(n). LinkedList insertion sort is also O(n).
Section G

Short Answer Questions (8)

Q1. What is the difference between Collection and Collections in Java?

Answer: Collection (singular) is a root interface in java.util that represents a group of objects (extended by List, Set, Queue). Collections (plural) is a utility class in java.util that provides static helper methods like sort(), reverse(), shuffle(), max(), min(), unmodifiableList(). Analogy: Collection is the blueprint of a library; Collections is the librarian who organises books.

Q2. Why doesn't Map extend the Collection interface?

Answer: Collection stores single elements (Collection<E>), while Map stores key-value pairs (Map<K,V>). Their fundamental contracts are different โ€” Collection has add(E), Map has put(K,V). Forcing Map to extend Collection would require awkward compromises. However, Map provides keySet(), values(), and entrySet() to expose its contents as Collections.

Q3. What is the load factor in HashMap and why is the default 0.75?

Answer: Load factor = (number of entries / number of buckets). It determines when to resize. Default 0.75 means HashMap resizes when 75% full. This is a balanced trade-off: too low (0.5) = more memory, fewer collisions, faster; too high (1.0) = less memory, more collisions, slower. 0.75 is empirically optimal for most use cases, as recommended by Java documentation.

Q4. Explain fail-fast vs fail-safe iterators with examples.

Answer: Fail-fast iterators (ArrayList, HashMap, HashSet) throw ConcurrentModificationException if the collection is structurally modified during iteration. They use an internal modCount field. Fail-safe iterators (ConcurrentHashMap, CopyOnWriteArrayList) work on a copy/snapshot, so modifications don't affect iteration. Example: new ArrayList<>().iterator() is fail-fast; new ConcurrentHashMap<>().keySet().iterator() is fail-safe.

Q5. How does TreeSet maintain sorted order?

Answer: TreeSet uses a Red-Black Tree (a self-balancing binary search tree) internally. Every insertion triggers tree rebalancing to maintain the BST property (left < parent < right). Elements must implement Comparable or a Comparator must be provided. All operations (add, remove, contains) are O(log n) due to tree height being O(log n).

Q6. What happens internally when you call hashMap.put(key, value)?

Answer: Step 1: Compute hash = key.hashCode(), then spread it: hash ^ (hash >>> 16). Step 2: Find bucket index: index = hash & (capacity - 1). Step 3: If bucket is empty, create a new Node and place it there. Step 4: If bucket is occupied, traverse the linked list/tree using equals(). If matching key found, replace value. If not found, append new Node. Step 5: If list length exceeds 8, treeify. Step 6: If size exceeds threshold (capacity ร— loadFactor), resize to 2ร— capacity.

Q7. Why should you override both hashCode() and equals() for HashMap keys?

Answer: HashMap uses hashCode() to find the bucket and equals() to find the exact key within the bucket. If only equals() is overridden, two equal objects may have different hashCodes (from Object.hashCode()), landing in different buckets โ€” so get() won't find the key. Contract: if a.equals(b) is true, then a.hashCode() == b.hashCode() must also be true.

Q8. Compare ArrayDeque with Stack and LinkedList for stack operations.

Answer: ArrayDeque is the recommended replacement for both. vs Stack: Stack extends Vector (synchronized, slow). ArrayDeque has no synchronization overhead and is 3โ€“4ร— faster. vs LinkedList: LinkedList allocates a new node object per element (GC pressure, cache misses). ArrayDeque uses a resizable array (contiguous memory, cache-friendly). Java docs explicitly state: "This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue."

Section H

Long Answer Questions (3)

Q1. Explain the internal working of HashMap in Java with a diagram. Cover: hashing, bucket array, collision handling (chaining), treeification, and resizing. [10 marks]

Answer:

(a) Hashing: When put(K, V) is called, HashMap computes the hash of the key: int hash = key.hashCode(); hash = hash ^ (hash >>> 16);. The XOR with the upper 16 bits reduces collision probability by spreading the hash bits.

(b) Bucket Index: The bucket index is calculated as index = hash & (n-1) where n = array length (always a power of 2). This is equivalent to hash % n but faster (bitwise AND).

(c) Storage: The bucket array Node<K,V>[] table starts with 16 slots. Each slot (bucket) is initially null. When an entry is added, a Node object (containing hash, key, value, next pointer) is placed at the computed index.

(d) Collision Handling (Chaining): When two keys hash to the same index, a collision occurs. The new Node is appended to the linked list in that bucket. On get(K), the chain is traversed using equals() to find the matching key.

(e) Treeification (Java 8+): When a bucket's linked list exceeds TREEIFY_THRESHOLD (8 nodes), it's converted to a Red-Black Tree for O(log n) lookup instead of O(n). This prevents worst-case performance when many keys hash to the same bucket.

(f) Resizing: When total entries exceed capacity ร— loadFactor (default: 16 ร— 0.75 = 12), HashMap doubles the array to 32 and rehashes all entries. This is called rehashing. The new index for each entry may change since hash & (newN-1) uses an additional bit.

Time Complexity: O(1) average for put/get/remove. O(log n) worst case per bucket (treeified). O(n) worst case overall only if resize is triggered.

Q2. Compare List, Set, and Map interfaces in Java with at least 8 differences. Provide real-world examples for each. [10 marks]

Answer:

#ParameterListSetMap
1Duplicatesโœ… AllowedโŒ Not allowedKeys: โŒ, Values: โœ…
2OrderInsertion order maintainedDepends (HashSet: no, TreeSet: sorted, LinkedHashSet: insertion)Depends on implementation
3Null elementsMultiple nulls1 null (HashSet), 0 (TreeSet)1 null key (HashMap), 0 (TreeMap)
4Access by indexโœ… get(index)โŒ No indexโœ… get(key)
5Parent interfaceCollectionCollectionNOT Collection (separate)
6Storage unitSingle element ESingle element EKey-Value pair (K, V)
7IteratorIterator + ListIteratorIterator onlyIterator via entrySet/keySet
8Example classArrayList, LinkedListHashSet, TreeSetHashMap, TreeMap

Real-world examples: List = Flipkart shopping cart (ordered items, duplicates allowed โ€” buy 2 of same). Set = Aadhaar database (each citizen has one unique ID). Map = PhonePe contact-to-UPI mapping (name โ†’ UPI ID, instant lookup).

Q3. Discuss Comparable vs Comparator with complete code examples. When would you use one over the other? [10 marks]

Answer:

Comparable (java.lang.Comparable<T>): Defines the natural ordering of a class by implementing compareTo(T other) inside the class itself. Only ONE ordering per class. Used when the class has an obvious default sort order (e.g., String: alphabetical, Integer: ascending).

Comparator (java.util.Comparator<T>): Defines external, custom orderings without modifying the original class. Implements compare(T o1, T o2). Supports MULTIPLE orderings (sort by name, by age, by salary). Can be passed to Collections.sort(), TreeSet, TreeMap, PriorityQueue.

When to use Comparable: (1) You own the class and want a default order. (2) There's one obvious natural order. (3) Example: Student sorted by rollNo by default.

When to use Comparator: (1) You don't own the class (third-party). (2) Multiple sort orders needed. (3) Lambda expressions make it concise in Java 8+. Example: Sort employees by salary, then by name, then by department โ€” three different Comparators.

Java 8 shortcuts: Comparator.comparing(Student::getName), Comparator.comparing(Student::getPercentage).reversed(), Comparator.comparing(Student::getName).thenComparing(Student::getAge).

Section I

Lab Program 4 โ€” Managing Multiple Items with ArrayList

๐Ÿ”ฌ Lab 4: ArrayList Operations โ€” Iteration, Add, Remove, Update

โฑ๏ธ 90 minutesBeginnerCore Lab โ€” Exam & Viva Important

Objective:

Write a Java program to manage a list of items (e.g., grocery items) using ArrayList. Implement: add item, remove item by name, update item by index, display all items, and iterate using all three methods (for loop, for-each, Iterator).

Full Code:

Java
/*
 * Lab 4: Managing Multiple Items with ArrayList
 * Course: Programming in Java โ€” Unit 13
 * Demonstrates: ArrayList operations โ€” add, remove, update, iterate
 */
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

public class Lab4_ArrayListManager {
    static ArrayList<String> items = new ArrayList<>();
    static Scanner sc = new Scanner(System.in);
    
    public static void main(String[] args) {
        // Pre-load some items
        items.add("Rice (5kg)");
        items.add("Toor Dal (1kg)");
        items.add("Sugar (2kg)");
        items.add("Milk (1L)");
        items.add("Bread (1 pack)");
        
        int choice;
        do {
            System.out.println("\nโ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—");
            System.out.println("โ•‘   ๐Ÿ›’ GROCERY LIST MANAGER        โ•‘");
            System.out.println("โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ");
            System.out.println("โ•‘ 1. Add Item                      โ•‘");
            System.out.println("โ•‘ 2. Remove Item by Name           โ•‘");
            System.out.println("โ•‘ 3. Update Item by Position       โ•‘");
            System.out.println("โ•‘ 4. Display All (for loop)        โ•‘");
            System.out.println("โ•‘ 5. Display All (for-each loop)   โ•‘");
            System.out.println("โ•‘ 6. Display All (Iterator)        โ•‘");
            System.out.println("โ•‘ 7. Check if item exists          โ•‘");
            System.out.println("โ•‘ 8. Exit                          โ•‘");
            System.out.println("โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•");
            System.out.print("Enter choice: ");
            choice = sc.nextInt();
            sc.nextLine(); // consume newline
            
            switch (choice) {
                case 1: addItem(); break;
                case 2: removeItem(); break;
                case 3: updateItem(); break;
                case 4: displayWithForLoop(); break;
                case 5: displayWithForEach(); break;
                case 6: displayWithIterator(); break;
                case 7: checkItem(); break;
                case 8: System.out.println("๐Ÿ‘‹ Goodbye!"); break;
                default: System.out.println("โŒ Invalid choice!");
            }
        } while (choice != 8);
    }
    
    // ADD โ€” O(1) amortized
    static void addItem() {
        System.out.print("Enter item name: ");
        String item = sc.nextLine();
        items.add(item);
        System.out.println("โœ… '" + item + "' added! Total items: " + items.size());
    }
    
    // REMOVE by name โ€” O(n)
    static void removeItem() {
        System.out.print("Enter item name to remove: ");
        String item = sc.nextLine();
        if (items.remove(item)) {
            System.out.println("โœ… '" + item + "' removed!");
        } else {
            System.out.println("โŒ Item not found!");
        }
    }
    
    // UPDATE by index โ€” O(1)
    static void updateItem() {
        displayWithForLoop();
        System.out.print("Enter position to update (1-" + items.size() + "): ");
        int pos = sc.nextInt();
        sc.nextLine();
        if (pos >= 1 && pos <= items.size()) {
            System.out.print("Enter new item name: ");
            String newItem = sc.nextLine();
            String old = items.set(pos - 1, newItem); // set() returns old value
            System.out.println("โœ… '" + old + "' updated to '" + newItem + "'");
        } else {
            System.out.println("โŒ Invalid position!");
        }
    }
    
    // ITERATION METHOD 1: Traditional for loop
    static void displayWithForLoop() {
        System.out.println("\n--- Grocery List (for loop) ---");
        for (int i = 0; i < items.size(); i++) {
            System.out.println((i + 1) + ". " + items.get(i));
        }
        System.out.println("Total: " + items.size() + " items");
    }
    
    // ITERATION METHOD 2: Enhanced for-each loop
    static void displayWithForEach() {
        System.out.println("\n--- Grocery List (for-each) ---");
        int count = 1;
        for (String item : items) {
            System.out.println(count++ + ". " + item);
        }
    }
    
    // ITERATION METHOD 3: Iterator (safe for removal during iteration)
    static void displayWithIterator() {
        System.out.println("\n--- Grocery List (Iterator) ---");
        Iterator<String> it = items.iterator();
        int count = 1;
        while (it.hasNext()) {
            System.out.println(count++ + ". " + it.next());
        }
    }
    
    // CHECK existence โ€” O(n)
    static void checkItem() {
        System.out.print("Enter item to search: ");
        String item = sc.nextLine();
        if (items.contains(item)) {
            System.out.println("โœ… Found at position: " + (items.indexOf(item) + 1));
        } else {
            System.out.println("โŒ Item not in list.");
        }
    }
}
โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ ๐Ÿ›’ GROCERY LIST MANAGER โ•‘ โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ โ•‘ 1. Add Item โ•‘ โ•‘ 2. Remove Item by Name โ•‘ โ•‘ 3. Update Item by Position โ•‘ โ•‘ 4. Display All (for loop) โ•‘ ... Enter choice: 4 --- Grocery List (for loop) --- 1. Rice (5kg) 2. Toor Dal (1kg) 3. Sugar (2kg) 4. Milk (1L) 5. Bread (1 pack) Total: 5 items

Viva Questions (5):

  1. Q: What is the default initial capacity of ArrayList?
    A: 10. When the 11th element is added, ArrayList grows by 50% (new capacity = old ร— 1.5). So it becomes 15, then 22, then 33, and so on.
  2. Q: What is the difference between remove(int index) and remove(Object o)?
    A: remove(int) removes the element at the specified index (O(n) due to shifting). remove(Object) removes the first occurrence of the specified element using equals() (O(n) for search + shifting). For ArrayList<Integer>, use remove(Integer.valueOf(5)) to remove value 5, not index 5.
  3. Q: Why is ArrayList not thread-safe? How do you make it thread-safe?
    A: ArrayList has no synchronization on its methods. Use Collections.synchronizedList(new ArrayList<>()) or CopyOnWriteArrayList (for read-heavy use) for thread safety.
  4. Q: What happens if you call get(10) on an ArrayList of size 5?
    A: It throws IndexOutOfBoundsException at runtime. Always check index bounds: 0 โ‰ค index < size().
  5. Q: Can ArrayList store primitive types like int?
    A: No. ArrayList stores objects only. Use wrapper classes: ArrayList<Integer> instead of ArrayList<int>. Java's autoboxing automatically converts int โ†’ Integer and vice versa.
Section J

Industry Spotlight โ€” A Day in the Life

๐Ÿ‘ฉโ€๐Ÿ’ป Ananya Krishnan, 29 โ€” Backend Engineer at Flipkart, Bangalore

Background: B.Tech (CS) from NIT Trichy. Joined Flipkart as SDE-1 after campus placement. Promoted to SDE-2 in 2 years. Works on the Catalog and Inventory microservice โ€” the system that manages 150 million product listings.

A Typical Day:

9:30 AM โ€” Morning standup with the Catalog team. Discuss yesterday's production incident: HashMap in the pricing service had excessive collisions due to a bad hashCode() implementation for ProductCategory. Fix deployed overnight.

10:30 AM โ€” Code review for a junior engineer's PR. They used ArrayList where HashSet would be better for deduplication of seller IDs. Leave feedback: "ArrayList.contains() is O(n), HashSet.contains() is O(1). With 50K sellers, this matters."

11:30 AM โ€” Design discussion for new feature: "Similar Products" recommendation. Proposes using TreeMap<Double, List<Product>> where key = similarity score (sorted), value = list of products with that score.

1:00 PM โ€” Lunch at Flipkart's Koramangala campus. Chat with Data Science team about using PriorityQueue for ranking search results.

2:30 PM โ€” Implementing an LRU cache for product metadata using LinkedHashMap. Cache hit rate improved from 65% to 92%, reducing database calls by 3ร—.

4:30 PM โ€” Write unit tests for the cache. Use ConcurrentHashMap for thread safety since the cache is accessed by 200 concurrent threads during Big Billion Day.

6:00 PM โ€” Tech talk: "Collections Internals" โ€” presents HashMap's treeification deep-dive to the engineering team.

DetailInfo
Collections Used DailyHashMap, ConcurrentHashMap, ArrayList, TreeMap, PriorityQueue, LinkedHashMap (LRU Cache)
Entry Salary (SDE-1)โ‚น15โ€“22 LPA + ESOPs
Mid-Level (SDE-2, 3-5 yrs)โ‚น25โ€“40 LPA
Senior (SDE-3, 7+ yrs)โ‚น45โ€“70 LPA
Companies Using Collections HeavilyFlipkart, Amazon, Google, Zomato, Swiggy, PhonePe, Razorpay, Zerodha, CRED
Ananya's advice to students: "Don't just memorize Collections APIs. Understand the WHY. Why is HashMap O(1)? Why does treeification happen at 8? When you can answer these, you stand out in interviews. I rejected 3 candidates last month who could use HashMap but couldn't explain how it works internally."
Section K

Earn With It โ€” Freelance & Income Roadmap

๐Ÿ’ฐ Your Earning Path After This Unit: โ‚น10Kโ€“โ‚น30K/month

Portfolio Piece: Student Result Management System / Inventory Management System โ€” menu-driven, uses ArrayList, HashMap, TreeMap, PriorityQueue. Host on GitHub.

Gig Ideas:

โ€ข Data processing CLI tools for small businesses (CSV โ†’ filtered/sorted reports) โ€” โ‚น5,000โ€“โ‚น12,000

โ€ข Inventory management desktop apps for kirana stores โ€” โ‚น8,000โ€“โ‚น20,000

โ€ข Student/employee management systems for coaching centres โ€” โ‚น5,000โ€“โ‚น15,000

โ€ข Custom data filtering/sorting tools for data entry companies โ€” โ‚น3,000โ€“โ‚น8,000

PlatformBest ForTypical Rate
InternshalaJava intern projects, campus gigsโ‚น5,000โ€“โ‚น15,000/project
FiverrQuick Java tools, data processing scripts$20โ€“$100/gig (โ‚น1,600โ€“โ‚น8,000)
UpworkLonger Java backend projects$20โ€“$50/hour
LinkedInDirect outreach to startups needing Java devsโ‚น10,000โ€“โ‚น30,000/project
GitHub PortfolioShowcasing projects for placementsPriceless for landing โ‚น6โ€“15 LPA jobs
The real earning power of Collections knowledge is in placements. Every product company interview (Flipkart, Amazon, Google, Microsoft) asks 2โ€“3 Collections questions. Mastering this unit directly translates to landing โ‚น10โ€“25 LPA packages. That's โ‚น83Kโ€“โ‚น2L/month โ€” far beyond freelancing.
Section L

Chapter Summary

๐Ÿ“ Key Takeaways โ€” Unit 13: Collections Framework

  1. Collection Hierarchy: Iterable โ†’ Collection โ†’ List (ordered, duplicates) / Set (unique) / Queue (FIFO). Map is separate (key-value).
  2. ArrayList = dynamic array, O(1) random access, best for 90% of use cases. Default choice.
  3. LinkedList = doubly-linked nodes, O(1) insert/delete at known positions, implements Deque.
  4. HashSet = backed by HashMap, O(1) operations, no duplicates, no order.
  5. TreeSet = Red-Black Tree, O(log n), sorted order, no null.
  6. HashMap = array of buckets + linked list/tree, O(1) avg, 16 initial capacity, 0.75 load factor, treeifies at 8.
  7. TreeMap = sorted by key, O(log n), great for range queries.
  8. LinkedHashMap = insertion/access order, O(1), perfect for LRU Cache.
  9. PriorityQueue = min-heap, O(log n) insert/remove, priority-based processing.
  10. Iterator = safe removal during iteration. Always use Iterator.remove(), never list.remove() inside for-each.
  11. Comparable = natural order (inside class). Comparator = custom order (external, multiple).
  12. Override both hashCode() AND equals() when using custom objects as HashMap keys or HashSet elements.

๐Ÿฆ Code Tweet โ€” Unit 13 in 280 Characters

Java Collections in 1 tweet:
ArrayListโ†’O(1) read, HashMapโ†’O(1) lookup,
TreeMapโ†’sorted keys, HashSetโ†’no dupes,
PriorityQueueโ†’min-heap, Iteratorโ†’safe remove,
Comparableโ†’natural, Comparatorโ†’custom.
Override hashCode()+equals() or regret it. ๐Ÿ”ฅ #Java

Section M

Checkpoint โ€” Self-Assessment

TopicSkill LevelPortfolio PieceInterview Ready?
Collection HierarchyConceptualโ€”โœ… Yes โ€” can draw hierarchy from memory
ArrayList OperationsHands-on (Lab 4)Grocery List Managerโœ… Yes โ€” add/remove/update/iterate
HashMap InternalsDeep Conceptual + CodeFlipkartCatalogโœ… Yes โ€” hashing, buckets, treeification
HashSet / TreeSetConceptual + CodeVoterBooth Exampleโœ… Yes โ€” uniqueness, sorting
PriorityQueueConceptual + CodeFlash Deal Countdownโœ… Yes โ€” min-heap, custom Comparator
TreeMap / LinkedHashMapConceptual + CodeSorted Student Marksโœ… Yes โ€” sorted keys, LRU cache
Iterator / ListIteratorHands-onSafe Removal Exampleโœ… Yes โ€” ConcurrentModificationException
Comparable vs ComparatorConceptual + CodeStudentResultSystemโœ… Yes โ€” natural vs custom ordering
IRCTC Waitlist SystemFull ProjectIRCTCWaitlistโœ… Yes โ€” Queue + HashMap + ArrayList
LRU CacheInterview-LevelLRUCacheโœ… Yes โ€” LinkedHashMap access-order
Minimum Viable Portfolio after this unit: A GitHub repository with 3 projects (StudentResultSystem, FlipkartCatalog, IRCTCWaitlist) + Lab 4 code + ability to explain HashMap internals on a whiteboard = you're interview-ready for Collections questions at any Indian tech company.

โœ… Unit 13 complete. MCQs: 30. Lab 4 covered. Ready for Unit 14!

[QR: Link to EduArtha video tutorial โ€” Java Collections Framework]