---
# System prepended metadata

title: Untitled

---

### Script for Lecture on Generics and Collections

---

#### **0-5 mins: Introduction and Problem Statement**

- **Start with a relatable example**:  
  Ask, "Have you ever written code that feels repetitive, like defining similar methods or classes for different data types?"  
  - Example: A class `PairOfIntegers` for integers and another `PairOfStrings` for strings.

- **Highlight the problem**:  
  Without generics, we'd need separate classes or methods for each data type, which is redundant and error-prone. Generics solve this by allowing **type-safe, reusable code**.

---

#### **5-25 mins: Introduction to Generics with a `Pair` Example**

1. **Explain Generics through a Pair class**:
   - A class `Pair` that holds two objects of the same type.
   - Discuss how generics help make the `Pair` class reusable for any type.

2. **Walkthrough on the code editor**:
   ```java
   class Pair<T> {
       private T first;
       private T second;

       public Pair(T first, T second) {
           this.first = first;
           this.second = second;
       }

       public T getFirst() {
           return first;
       }

       public T getSecond() {
           return second;
       }

       public void setFirst(T first) {
           this.first = first;
       }

       public void setSecond(T second) {
           this.second = second;
       }
   }

   public class Main {
       public static void main(String[] args) {
           Pair<String> stringPair = new Pair<>("Hello", "World");
           System.out.println("First: " + stringPair.getFirst());
           System.out.println("Second: " + stringPair.getSecond());
       }
   }
   ```

3. **Explain step-by-step**:
   - What `T` is and how it gets replaced at runtime.
   - The advantages: type safety, no casting, and code reuse.

---

#### **25-40 mins: Where Type Parameters Can Be Used**

1. **In Classes**:  
   - Example: `Pair<V, T>`.  
     Discuss that classes can use **multiple type parameters**.

2. **In Methods**:  
   - Example: A static method to swap elements in an array.
     ```java
     public static <T> void swap(T[] array, int i, int j) {
         T temp = array[i];
         array[i] = array[j];
         array[j] = temp;
     }
     ```

3. **Discuss flexibility**:  
   - Type parameters can be used in constructors, methods, and fields.

---

#### **40-55 mins: Generics with Collections**

1. **Introduce Collections**:  
   - Explain `Collection<T>` as a generic interface and how its subclasses like `List<T>` use generics.

2. **Example**:
   ```java
   List<String> stringList = new ArrayList<>();
   stringList.add("Hello");
   stringList.add("Generics");

   for (String s : stringList) {
       System.out.println(s);
   }
   ```

3. **Explain the key points**:
   - No need for casting while retrieving elements.
   - Compile-time type checking ensures type safety.

---

#### **55-60 mins: Raw Types**

- Explain what raw types are and their limitations:
  ```java
  List list = new ArrayList(); // Raw type
  list.add("String");
  list.add(123); // No type safety
  ```

- Discuss why raw types are discouraged in modern Java.

---

#### **60-80 mins: Bounds and Wildcards in Generics**

1. **Start with bounds (`T extends` and `T super`)**:
   - Example: A bounded type parameter.
     ```java
     public static <T extends Number> double sum(T a, T b) {
         return a.doubleValue() + b.doubleValue();
     }
     ```

2. **Introduce wildcards**:
   - `? extends T`: For read flexibility.
   - `? super T`: For write flexibility.

3. **Example**:
   ```java
   void processNumbers(List<? extends Number> numbers) {
       for (Number number : numbers) {
           System.out.println(number);
       }
   }
   ```

4. **Explain the scenarios**:
   - When to use wildcards vs bounded type parameters.

---

#### **80-125 mins: Introduction to the Collection Framework**

1. **Overview of Collection Framework**:
   - Discuss the hierarchy:
     - `Collection<T>` interface.
     - Subinterfaces: `List<T>`, `Set<T>`, `Queue<T>`.
     - Implementations: `ArrayList`, `HashSet`, `LinkedList`, etc.

2. **Differences Between Collections**:
   - Use a table format or diagram to explain:
     | Collection Type | Allows Duplicates | Ordered | Example Use Case        |
     |-----------------|------------------|---------|-------------------------|
     | `List`         | Yes              | Yes     | Dynamic arrays          |
     | `Set`          | No               | No      | Unique values           |
     | `Queue`        | Yes              | Depends | Task scheduling         |

3. **Quick Examples**:
   - `ArrayList`:
     ```java
     List<String> list = new ArrayList<>();
     list.add("A");
     list.add("B");
     ```
   - `HashSet`:
     ```java
     Set<String> set = new HashSet<>();
     set.add("A");
     set.add("A"); // Duplicate not added
     ```

4. **Introduce Map briefly**:
   - Explain `Map<K, V>` by taking an example of storing population of different countries



---

#### **Explaining Differences Between Implementations**

**1. List Interface Implementations**  
   - **`ArrayList`**:  
     - Backed by a dynamic array.  
     - Fast random access (`O(1)` for `get()`).
     - Slow insertions/deletions in the middle (`O(n)`).
     - Use Case: When frequent access is required, and the size grows dynamically.
   - **`LinkedList`**:  
     - Doubly-linked list structure.  
     - No random access; traversal required (`O(n)` for `get()`).
     - Fast insertions/deletions at both ends (`O(1)` at head/tail).  
     - Use Case: When insertions and deletions are frequent.

---

**2. Set Interface Implementations**  
   - **`HashSet`**:  
     - Backed by a hash table.
     - No order guarantee.
     - Fast operations (`O(1)` for add, remove, contains).
     - Use Case: Maintaining unique elements where order doesn’t matter.  
   - **`LinkedHashSet`**:  
     - Preserves insertion order.
     - Slower than `HashSet` due to extra linking overhead.
     - Use Case: Maintaining unique elements with insertion order.  
   - **`TreeSet`**:  
     - Backed by a red-black tree.
     - Keeps elements sorted (natural/comparator-defined).
     - Slower (`O(log n)` for add, remove, contains).
     - Use Case: Maintaining sorted unique elements.

---

**3. Queue Interface Implementations**  
   - **`PriorityQueue`**:  
     - Elements are ordered by natural order or comparator.
     - Not thread-safe.
     - Use Case: Task scheduling, where priority matters.
   - **`LinkedList`** (as Queue):  
     - Implements `Deque` and supports FIFO order.
     - Use Case: Simple queue operations.  

---

**4. Map Interface Implementations**  
   - **`HashMap`**:  
     - Backed by a hash table.
     - Fast lookups and updates (`O(1)` for put/get).
     - No order guarantee.
     - Use Case: General-purpose key-value storage.  
   - **`LinkedHashMap`**:  
     - Preserves insertion order.
     - Slightly slower than `HashMap` due to additional linking.
     - Use Case: Caching mechanisms.  
   - **`TreeMap`**:  
     - Backed by a red-black tree.
     - Keeps keys sorted.
     - Slower (`O(log n)` for put/get).
     - Use Case: Sorted key-value storage.  

---

#### **Quick Comparison Table**

| **Feature**         | **ArrayList** | **LinkedList** | **HashSet** | **TreeSet** | **PriorityQueue** |
|---------------------|---------------|----------------|-------------|-------------|-------------------|
| **Ordering**        | Index-based   | Sequence       | None        | Sorted      | Priority-based    |
| **Duplicates**      | Allowed       | Allowed        | Not Allowed | Not Allowed | Allowed           |
| **Access Time**     | `O(1)`        | `O(n)`         | `O(1)`      | `O(log n)`  | `O(log n)`        |
| **Insertion/Deletion** | `O(n)`      | `O(1)` (ends)  | `O(1)`      | `O(log n)`  | `O(log n)`        |
| **Use Case**        | Random Access | Frequent Add/Delete | Unique Elements | Sorted Elements | Task Priority    |

---


