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

OperationComplexityReason
get(index)O(1)Direct array access
add(element)O(1)*Amortized
add(index)O(n)Shifting elements
remove(index)O(n)Shifting elements
searchO(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

  1. Compute hash

  2. Find bucket index

  3. If empty → insert

  4. If collision:

    • Traverse bucket
    • Use equals() to match keys
    • If key exists → overwrite value
    • Else → add new node

šŸ“Œ 6. Time Complexity

OperationAverageWorst 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 selection
    • equals() → key comparison

šŸ‘‰ Both must be consistent


šŸ“Œ 9. Characteristics

  • Allows:

    • One null key
    • Multiple null values
  • No ordering guarantee

  • Not thread-safe


šŸ”„ Key Differences (Interview Summary)

FeatureArrayListHashMap
StructureDynamic ArrayArray + Buckets
AccessBy indexBy key
ComplexityO(1) readO(1) average lookup
OrderingMaintainedNot maintained
NullsAllowed1 null key allowed
Use CaseIndexed storageKey-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.

Internal working of ArrayList and HashMap. | DevExCode