Home/Java/Map in Java

Map in Java

Learn about key-value pair collections

💡 Think of a Map like a dictionary - each word (key) has its meaning (value)! You look up the word to find its definition. Just like you can't have the same word twice in a dictionary, each key in a Map must be unique, but values can repeat!

📖 What is a Map?

A Map is an object that stores key-value pairs. Each key maps to exactly one value. Maps are perfect for fast lookup, where you need to find data based on a unique identifier. Keys must be unique, but values can be duplicated.

BasicHashMap.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.util.HashMap;
import java.util.Map;
public class BasicHashMap {
public static void main(String[] args) {
// Creating a HashMap
Map<String, String> capitals = new HashMap<>();
// Adding key-value pairs using put()
capitals.put("USA", "Washington DC");
capitals.put("France", "Paris");
capitals.put("Japan", "Tokyo");
capitals.put("India", "New Delhi");
System.out.println("Capitals: " + capitals);
// Getting values by key
String usCapital = capitals.get("USA");
System.out.println("\nCapital of USA: " + usCapital);
// Checking if key exists
boolean hasFrance = capitals.containsKey("France");
System.out.println("Has France? " + hasFrance); // true
// Checking if value exists
boolean hasParis = capitals.containsValue("Paris");
System.out.println("Has Paris? " + hasParis); // true
// Size of the map
System.out.println("\nTotal entries: " + capitals.size());
// Updating a value (put with existing key)
capitals.put("USA", "New York"); // Replaces Washington DC
System.out.println("Updated USA: " + capitals.get("USA"));
// Removing an entry
capitals.remove("Japan");
System.out.println("After removing Japan: " + capitals);
// Using getOrDefault
String ukCapital = capitals.getOrDefault("UK", "Not Found");
System.out.println("\nUK Capital: " + ukCapital); // Not Found
}
}

🔍 🗂️ Types of Maps

Java provides different Map implementations for different scenarios:

1

HashMap

Fastest lookup, uses hashing, no guaranteed order, allows one null key

2

LinkedHashMap

Maintains insertion order or access order, slightly slower than HashMap

3

TreeMap

Keys sorted in natural order or by comparator, slowest but sorted

4

Hashtable

Thread-safe, legacy class, no null keys or values (use ConcurrentHashMap instead)

ComparingMapTypes.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.*;
public class ComparingMapTypes {
public static void main(String[] args) {
// Same data added to different maps
String[][] countries = {
{"USA", "Washington DC"},
{"France", "Paris"},
{"Japan", "Tokyo"},
{"India", "New Delhi"}
};
// 1. HashMap - Fast, no guaranteed order
Map<String, String> hashMap = new HashMap<>();
for (String[] pair : countries) {
hashMap.put(pair[0], pair[1]);
}
System.out.println("HashMap (random order):");
hashMap.forEach((k, v) -> System.out.println(" " + k + " -> " + v));
// 2. LinkedHashMap - Maintains insertion order
Map<String, String> linkedHashMap = new LinkedHashMap<>();
for (String[] pair : countries) {
linkedHashMap.put(pair[0], pair[1]);
}
System.out.println("\nLinkedHashMap (insertion order):");
linkedHashMap.forEach((k, v) -> System.out.println(" " + k + " -> " + v));
// 3. TreeMap - Sorted by keys
Map<String, String> treeMap = new TreeMap<>();
for (String[] pair : countries) {
treeMap.put(pair[0], pair[1]);
}
System.out.println("\nTreeMap (sorted by key):");
treeMap.forEach((k, v) -> System.out.println(" " + k + " -> " + v));
// TreeMap specific methods
TreeMap<String, String> sortedMap = (TreeMap<String, String>) treeMap;
System.out.println("\nFirst key: " + sortedMap.firstKey());
System.out.println("Last key: " + sortedMap.lastKey());
}
}

📞 Real-World Example: Phone Book

PhoneBook.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import java.util.HashMap;
import java.util.Map;
public class PhoneBook {
private Map<String, String> contacts;
public PhoneBook() {
this.contacts = new HashMap<>();
}
// Add a contact
public void addContact(String name, String phoneNumber) {
contacts.put(name, phoneNumber);
System.out.println("Added: " + name + " -> " + phoneNumber);
}
// Update a contact
public void updateContact(String name, String newNumber) {
if (contacts.containsKey(name)) {
String oldNumber = contacts.put(name, newNumber);
System.out.println("Updated " + name + " from " + oldNumber + " to " + newNumber);
} else {
System.out.println(name + " not found!");
}
}
// Find a phone number
public String findNumber(String name) {
return contacts.getOrDefault(name, "Contact not found");
}
// Remove a contact
public void removeContact(String name) {
if (contacts.remove(name) != null) {
System.out.println("Removed: " + name);
} else {
System.out.println(name + " not found!");
}
}
// Check if contact exists
public boolean hasContact(String name) {
return contacts.containsKey(name);
}
// Print all contacts
public void printAllContacts() {
System.out.println("\n=== Phone Book ===");
if (contacts.isEmpty()) {
System.out.println("No contacts!");
} else {
contacts.forEach((name, number) ->
System.out.println(name + ": " + number));
}
System.out.println("Total contacts: " + contacts.size());
}
public static void main(String[] args) {
PhoneBook phoneBook = new PhoneBook();
// Add contacts
phoneBook.addContact("Alice", "555-1234");
phoneBook.addContact("Bob", "555-5678");
phoneBook.addContact("Charlie", "555-9012");
// Look up a number
System.out.println("\nAlice's number: " + phoneBook.findNumber("Alice"));
// Update a contact
phoneBook.updateContact("Bob", "555-0000");
// Print all contacts
phoneBook.printAllContacts();
// Remove a contact
phoneBook.removeContact("Charlie");
phoneBook.printAllContacts();
// Try to find removed contact
System.out.println("\nCharlie's number: " + phoneBook.findNumber("Charlie"));
}
}

📊 Real-World Example: Word Counter

WordCounter.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.util.*;
public class WordCounter {
public static void main(String[] args) {
String text = "the quick brown fox jumps over the lazy dog the fox is quick";
// Count word frequencies
Map<String, Integer> wordCount = new HashMap<>();
// Split text into words
String[] words = text.split("\\s+");
// Count each word
for (String word : words) {
word = word.toLowerCase();
// Method 1: Traditional way
// if (wordCount.containsKey(word)) {
// wordCount.put(word, wordCount.get(word) + 1);
// } else {
// wordCount.put(word, 1);
// }
// Method 2: Using getOrDefault (better)
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
// Method 3: Using merge (best)
// wordCount.merge(word, 1, Integer::sum);
}
// Print word frequencies
System.out.println("Word Frequencies:");
wordCount.forEach((word, count) ->
System.out.println(word + ": " + count));
// Find most common word
String mostCommon = null;
int maxCount = 0;
for (Map.Entry<String, Integer> entry : wordCount.entrySet()) {
if (entry.getValue() > maxCount) {
maxCount = entry.getValue();
mostCommon = entry.getKey();
}
}
System.out.println("\nMost common word: '" + mostCommon +
"' (appears " + maxCount + " times)");
// Sort by frequency (descending)
System.out.println("\nSorted by frequency:");
wordCount.entrySet().stream()
.sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
.forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));
// Words that appear more than once
System.out.println("\nWords appearing more than once:");
wordCount.entrySet().stream()
.filter(e -> e.getValue() > 1)
.forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));
}
}

🎓 Real-World Example: Student ID System

StudentIDSystem.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.util.*;
class Student {
String name;
int age;
double gpa;
public Student(String name, int age, double gpa) {
this.name = name;
this.age = age;
this.gpa = gpa;
}
@Override
public String toString() {
return name + " (Age: " + age + ", GPA: " + gpa + ")";
}
}
public class StudentIDSystem {
private Map<String, Student> students;
public StudentIDSystem() {
this.students = new HashMap<>();
}
// Register a student
public void registerStudent(String id, String name, int age, double gpa) {
Student student = new Student(name, age, gpa);
students.put(id, student);
System.out.println("Registered: " + id + " -> " + student);
}
// Find student by ID
public Student findStudent(String id) {
return students.get(id);
}
// Update student GPA
public void updateGPA(String id, double newGPA) {
Student student = students.get(id);
if (student != null) {
student.gpa = newGPA;
System.out.println("Updated " + id + " GPA to " + newGPA);
} else {
System.out.println("Student " + id + " not found!");
}
}
// Get all students with GPA above threshold
public void printHighPerformers(double threshold) {
System.out.println("\nStudents with GPA >= " + threshold + ":");
students.forEach((id, student) -> {
if (student.gpa >= threshold) {
System.out.println(" " + id + ": " + student);
}
});
}
// Print all students
public void printAllStudents() {
System.out.println("\n=== All Students ===");
students.forEach((id, student) ->
System.out.println(id + ": " + student));
System.out.println("Total students: " + students.size());
}
public static void main(String[] args) {
StudentIDSystem system = new StudentIDSystem();
// Register students
system.registerStudent("S001", "Alice", 20, 3.8);
system.registerStudent("S002", "Bob", 21, 3.5);
system.registerStudent("S003", "Charlie", 19, 3.9);
system.registerStudent("S004", "David", 22, 3.2);
// Find a student
System.out.println("\nLooking up S002:");
Student bob = system.findStudent("S002");
System.out.println(bob);
// Update GPA
system.updateGPA("S002", 3.7);
// Print all students
system.printAllStudents();
// High performers
system.printHighPerformers(3.7);
}
}

🔧 Common Map Operations

MapOperations.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.util.*;
public class MapOperations {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
// 1. Adding entries
scores.put("Alice", 95);
scores.put("Bob", 87);
scores.put("Charlie", 92);
// 2. putIfAbsent - only add if key doesn't exist
scores.putIfAbsent("Alice", 100); // Won't replace 95
scores.putIfAbsent("David", 88); // Will add
// 3. Iterating through map
System.out.println("Using entrySet (most efficient):");
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
System.out.println("\nUsing keySet:");
for (String name : scores.keySet()) {
System.out.println(name + ": " + scores.get(name));
}
System.out.println("\nUsing values:");
for (Integer score : scores.values()) {
System.out.println("Score: " + score);
}
System.out.println("\nUsing forEach:");
scores.forEach((name, score) ->
System.out.println(name + ": " + score));
// 4. Compute methods
scores.compute("Alice", (key, val) -> val + 5); // Add 5 to Alice's score
scores.computeIfAbsent("Eve", key -> 90); // Add Eve with score 90
scores.computeIfPresent("Bob", (key, val) -> val + 10); // Add 10 to Bob
// 5. merge - combine values
scores.merge("Charlie", 8, Integer::sum); // Add 8 to Charlie's score
// 6. replace methods
scores.replace("David", 95); // Replace David's score
scores.replace("Bob", 97, 100); // Replace only if current value is 97
// 7. Removing entries
scores.remove("Eve"); // Remove by key
scores.remove("Alice", 100); // Remove only if value matches
System.out.println("\nFinal scores: " + scores);
// 8. Bulk operations
Map<String, Integer> moreScores = new HashMap<>();
moreScores.put("Frank", 85);
moreScores.put("Grace", 93);
scores.putAll(moreScores); // Add all entries
// 9. Clear and size
System.out.println("Total entries: " + scores.size());
boolean isEmpty = scores.isEmpty();
}
}

🔑 Key Concepts

Key-Value Pairs

Each entry has a unique key and its associated value

('USA' -> 'Washington DC'), ('France' -> 'Paris')

Unique Keys

Each key can appear only once, adding same key replaces value

Adding ('USA' -> 'New York') replaces the previous value

Fast Lookup

Finding a value by key is very fast O(1) for HashMap

map.get('USA') instantly returns 'Washington DC'

No Duplicate Keys

Keys must be unique but values can repeat

Multiple countries can have same currency

Best Practices

  • Use HashMap for best performance when order doesn't matter
  • Use LinkedHashMap when you need predictable iteration order
  • Use TreeMap when you need keys sorted
  • Keys should be immutable (String, Integer, etc.) and properly implement equals() and hashCode()
  • Check if key exists with containsKey() before using get()
  • Use getOrDefault() to provide fallback values
  • Prefer Map interface type over implementation in declarations
  • Consider ConcurrentHashMap for thread-safe operations instead of Hashtable

💼 Interview Tips

  • HashMap uses array of linked lists/trees internally (buckets)
  • Default initial capacity is 16, load factor is 0.75
  • HashMap becomes TreeMap-like when bucket has 8+ elements (JDK 8+)
  • put() returns the previous value for the key (or null)
  • HashMap allows one null key and multiple null values
  • TreeMap doesn't allow null keys (NullPointerException)
  • Know how hashCode() and equals() affect HashMap performance
  • Understand collision resolution with chaining
  • entrySet() is more efficient than keySet() when you need both key and value