Java HashMap
Fast key-value storage with hash-based implementation
๐ What is HashMap?
HashMap is Java's most popular Map implementation that uses hashing for super-fast key-value storage. It provides constant-time performance for basic operations like get and put.
// Simple HashMap example
HashMap<String, Integer> ages = new HashMap<>();
ages.put("Alice", 25);
ages.put("Bob", 30);
System.out.println(ages.get("Alice")); // 25 - Very fast!
HashMap Key Features
Super Fast
O(1) average time for get/put operations
HashMap<String, String> cache = new HashMap<>();
cache.put("user123", "John Doe");
String user = cache.get("user123"); // Instant!
No Order
Elements are not stored in any order
HashMap<String, Integer> map = new HashMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
// Order may be: {B=2, A=1, C=3}
Null Values
Allows one null key and multiple null values
HashMap<String, String> map = new HashMap<>();
map.put(null, "null key value");
map.put("key1", null);
map.put("key2", null); // Multiple nulls OK
Not Thread-Safe
Use ConcurrentHashMap for threading
// For single-threaded use
HashMap<String, Integer> map = new HashMap<>();
// For multi-threaded use
ConcurrentHashMap<String, Integer> safeMap =
new ConcurrentHashMap<>();
๐น Creating and Using HashMap
Basic HashMap operations with examples:
import java.util.*;
public class HashMapExample {
public static void main(String[] args) {
// Create HashMap
HashMap<String, Double> productPrices = new HashMap<>();
// Add items
productPrices.put("Laptop", 999.99);
productPrices.put("Mouse", 25.50);
productPrices.put("Keyboard", 75.00);
productPrices.put("Monitor", 299.99);
// Get item price
double laptopPrice = productPrices.get("Laptop");
System.out.println("Laptop costs: $" + laptopPrice);
// Check if item exists
if (productPrices.containsKey("Mouse")) {
System.out.println("Mouse is available");
}
// Update price
productPrices.put("Mouse", 22.99); // Price reduced!
// Get with default value
double webcamPrice = productPrices.getOrDefault("Webcam", 0.0);
System.out.println("Webcam price: $" + webcamPrice);
// Display all products
System.out.println("\nAll products:");
for (Map.Entry<String, Double> entry : productPrices.entrySet()) {
System.out.println(entry.getKey() + ": $" + entry.getValue());
}
}
}
Output:
Laptop costs: $999.99
Mouse is available
Webcam price: $0.0
All products:
Laptop: $999.99
Mouse: $22.99
Keyboard: $75.0
Monitor: $299.99
๐น HashMap with Custom Objects
Using HashMap with custom objects as keys:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
// IMPORTANT: Override equals and hashCode for HashMap keys
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
// Usage
HashMap<Person, String> personJobs = new HashMap<>();
Person alice = new Person("Alice", 25);
Person bob = new Person("Bob", 30);
personJobs.put(alice, "Software Engineer");
personJobs.put(bob, "Data Scientist");
System.out.println(alice + " works as: " + personJobs.get(alice));
System.out.println("All employees: " + personJobs);
Output:
Alice(25) works as: Software Engineer
All employees: {Alice(25)=Software Engineer, Bob(30)=Data Scientist}
๐น HashMap Performance Tips
Best practices for optimal HashMap performance:
// 1. Set initial capacity if you know the size
HashMap<String, Integer> largeMap = new HashMap<>(1000);
// 2. Use proper load factor (default 0.75 is usually good)
HashMap<String, Integer> customMap = new HashMap<>(16, 0.75f);
// 3. Good hash code distribution is crucial
class GoodKey {
private String id;
private int number;
@Override
public int hashCode() {
return Objects.hash(id, number); // Good distribution
}
}
// 4. Avoid mutable keys
final class ImmutableKey {
private final String value;
ImmutableKey(String value) {
this.value = value;
}
// equals and hashCode methods...
}
// 5. Use putIfAbsent for conditional insertion
HashMap<String, List<String>> groups = new HashMap<>();
groups.putIfAbsent("admins", new ArrayList<>());
groups.get("admins").add("Alice");
// 6. Use compute methods for complex updates
HashMap<String, Integer> wordCount = new HashMap<>();
String[] words = {"hello", "world", "hello", "java"};
for (String word : words) {
wordCount.compute(word, (key, val) -> (val == null) ? 1 : val + 1);
}
System.out.println("Word counts: " + wordCount);
Output:
Word counts: {java=1, world=1, hello=2}