1. The Hook (The "Byte-Sized" Intro)
- In a Nutshell: Map stores key-value pairs—each key maps to exactly one value. Keys must be unique, values can duplicate.
- Main implementations: HashMap (fastest, no order), LinkedHashMap (insertion/access order), TreeMap (sorted by keys). Maps aren't part of Collection hierarchy but are essential for lookups, caching, and associative arrays.
Think of phone contacts. Name (key) → Phone number (value). Each name is unique, but multiple contacts can share a number. Instant lookup by name!
2. Conceptual Clarity (The "Simple" Tier)
💡 The Analogy: The Dictionary
- HashMap: Random page dictionary (fast, no alphabetical order)
- LinkedHashMap: Recent searches (remembers order)
- TreeMap: Alphabetical dictionary (sorted by keys)
3. Technical Mastery (The "Deep Dive")
Implementations Comparison
| Feature | HashMap | LinkedHashMap | TreeMap | Hashtable |
|---|---|---|---|---|
| Ordering | None | Insertion/access order | Sorted keys | None |
| Null keys | One | One | Zero (throws NPE) | Zero |
| Performance | O(1) | O(1) | O(log n) | O(1) |
| Thread-safe | No | No | No | Yes (legacy) |
4. Interactive & Applied Code
java
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
// HASHMAP: Fastest, no order
Map<String, Integer> ages = new HashMap<>();
ages.put("Alice", 25);
ages.put("Bob", 30);
ages.put("Alice", 26); // ❌ Overwrites previous value
System.out.println("HashMap: " + ages);
System.out.println("Alice's age: " + ages.get("Alice")); // 26
// LINKEDHASHMAP: Maintains insertion order
Map<String, String> countries = new LinkedHashMap<>();
countries.put("USA", "Washington");
countries.put("India", "Delhi");
countries.put("UK", "London");
System.out.println("LinkedHashMap: " + countries); // Insertion order
// TREEMAP: Sorted by keys
Map<String, Double> prices = new TreeMap<>();
prices.put("Banana", 1.5);
prices.put("Apple", 2.0);
prices.put("Cherry", 3.5);
System.out.println("TreeMap: " + prices); // {Apple=2.0, Banana=1.5, Cherry=3.5}
// Map methods
System.out.println("Contains 'Bob'? " + ages.containsKey("Bob"));
System.out.println("Contains value 30? " + ages.containsValue(30));
// Iterating Map.Entry
for (Map.Entry<String, Integer> entry : ages.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
// Java 8+ methods
ages.putIfAbsent("Charlie", 35); // Only if key absent
ages.computeIfPresent("Alice", (k, v) -> v + 1); // Alice = 27
ages.merge("Bob", 5, Integer::sum); // Bob = 30 + 5 = 35
// getOrDefault
int age = ages.getOrDefault("Unknown", 0); // Returns 0
System.out.println("Unknown age: " + age);
}
}5. The Comparison & Decision Layer
Decision Tree: Choosing a Map
graph TD
A{Need sorted keys?}
A -- Yes --> B[TreeMap]
A -- No --> C{Need insertion order?}
C -- Yes --> D[LinkedHashMap]
C -- No --> E[HashMap]
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question: "How does HashMap handle collisions?" Answer: HashMap uses separate chaining (Java 7) and balanced trees (Java 8+):
- Hash:
hashCode()determines bucket index - Collision: Multiple keys in same bucket
- Java 7: Linked list in bucket (O(n) worst case)
- Java 8+: If bucket has 8+ entries, converts to Red-Black Tree (O(log n))
This improves worst-case from O(n) to O(log n)!
Pro-Tip: LRU Cache with LinkedHashMap:
java
Map<String, String> lruCache = new LinkedHashMap<>(16, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > 100; // Max 100 entries
}
};
// `true` = access-order (most recent at end)Used by Android, web servers for caching!