collections
Internal working of ArrayList and HashMap.
# š¹ ArrayList Internals (Deep Dive) ## š 1. Core Structure - Backed by a **resizable array (`Object[] elementData`)** - Maintains: - `size` ā number of elements actually stored - `capacity` ā length of internal array š **Invariant:** `capacity >= size` --- ## š 2. Growth Mechanism When the internal array is full: ```java newCapacity = oldCapacity + (oldCapacity >> 1); // ~1.5x growth
- Example growth:
10 ā 15 ā 22 ā 33 ā ... - Uses:
Arrays.copyOf()
ā Why 1.5x?
- Reduces frequent resizing (better performance)
- Avoids excessive unused memory (better space efficiency)
š Trade-off: Time vs Space
š 3. Time Complexity
| Operation | Complexity | Reason |
|---|---|---|
| get(index) | O(1) | Direct array access |
| add(element) | O(1)* | Amortized |
| add(index) | O(n) | Shifting elements |
| remove(index) | O(n) | Shifting elements |
| search | O(n) | Linear scan |
š add() is amortized O(1) due to occasional resizing.
š 4. Key Characteristics
- Allows null values
- Maintains insertion order
- Not thread-safe (not synchronized)
š 5. Hidden Costs
- Resizing ā O(n) copy
- Insert/delete in middle ā O(n)
š Best for:
- Read-heavy scenarios
- Frequent index-based access
š¹ HashMap Internals (Deep Dive)
š 1. Core Structure
Node<K,V>[] table;
Each bucket contains:
- Linked List (Java 7)
- Linked List + Red-Black Tree (Java 8+)
š 2. Hashing Process
Step 1: Get hash
int hash = key.hashCode();
Step 2: Improve distribution
hash = hash ^ (hash >>> 16);
š Reduces collisions from poor hashCode() implementations
š 3. Bucket Index Calculation
index = (n - 1) & hash;
š Works because n is always a power of 2
š 4. Collision Handling
Before Java 8:
- Linked List ā O(n)
Java 8+:
- If bucket size ā„ 8 ā Red-Black Tree
- If size < 6 ā back to Linked List
š Improves worst-case performance:
- From O(n) ā O(log n)
š 5. Insertion Flow
-
Compute hash
-
Find bucket index
-
If empty ā insert
-
If collision:
- Traverse bucket
- Use
equals()to match keys - If key exists ā overwrite value
- Else ā add new node
š 6. Time Complexity
| Operation | Average | Worst Case |
|---|---|---|
| get() | O(1) | O(log n) |
| put() | O(1) | O(log n) |
| remove() | O(1) | O(log n) |
š 7. Load Factor & Resizing
- Default load factor = 0.75
Resize condition:
size > capacity * loadFactor
- On resize ā capacity doubles
š 8. Key Rules
-
Uses:
hashCode()ā bucket selectionequals()ā key comparison
š Both must be consistent
š 9. Characteristics
-
Allows:
- One
nullkey - Multiple
nullvalues
- One
-
No ordering guarantee
-
Not thread-safe
š„ Key Differences (Interview Summary)
| Feature | ArrayList | HashMap |
|---|---|---|
| Structure | Dynamic Array | Array + Buckets |
| Access | By index | By key |
| Complexity | O(1) read | O(1) average lookup |
| Ordering | Maintained | Not maintained |
| Nulls | Allowed | 1 null key allowed |
| Use Case | Indexed storage | Key-value mapping |
ā” One-Line Interview Answer
ArrayList provides fast index-based access using a dynamic array, while HashMap provides fast key-based lookup using hashing and bucket-based storage with collision handling.