HashMap basics

The HashMap class in Java is part of the java.util package and implements the Map interface. It provides the basic implementation of the Map interface, which is used to store key-value pairs. HashMap is an essential component of the Java Collections Framework and is widely used due to its efficiency and flexibility.

Key Features of HashMap

  1. No Duplicate Keys: Each key in a HashMap must be unique. If you try to insert a duplicate key, the old value associated with that key will be replaced by the new value.
  2. Allows Null Values and Keys: HashMap allows one null key and multiple null values.
  3. Unordered Collection: The entries in a HashMap are not ordered. The HashMap does not guarantee that the order will remain constant over time.
  4. High Performance: HashMap provides constant-time performance for basic operations (get and put), assuming the hash function disperses elements properly among the buckets.

Creating a HashMap

Here’s how to create a HashMap in Java:

import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> hashMap = new HashMap<>();
    }
}

Basic Operations

Adding Key-Value Pairs

To add key-value pairs to a HashMap, you can use the put method:

hashMap.put("Apple", 1);
hashMap.put("Banana", 2);
hashMap.put("Orange", 3);

Removing Key-Value Pairs

To remove key-value pairs from a HashMap, you can use the remove method:

hashMap.remove("Banana");

Retrieving Values

To retrieve values from a HashMap, you can use the get method:

int value = hashMap.get("Apple");  // returns 1

Checking for Keys or Values

To check if a HashMap contains a specific key or value, you can use the containsKey and containsValue methods:

boolean hasApple = hashMap.containsKey("Apple");  // returns true
boolean hasValue2 = hashMap.containsValue(2);  // returns false

Iterating Over Entries

To iterate over the entries in a HashMap, you can use an iterator, enhanced for loop, or forEach method:

// Using entrySet() and enhanced for loop
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// Using forEach method (Java 8 and later)
hashMap.forEach((key, value) -> System.out.println(key + ": " + value));

Example Program

Here’s a complete example demonstrating various operations with HashMap:

import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> hashMap = new HashMap<>();

        // Adding key-value pairs
        hashMap.put("Apple", 1);
        hashMap.put("Banana", 2);
        hashMap.put("Orange", 3);
        hashMap.put("Apple", 4);  // Duplicate key, value will be replaced

        // Checking size
        System.out.println("Size of hashMap: " + hashMap.size());  // Output: 3

        // Removing a key-value pair
        hashMap.remove("Banana");

        // Retrieving a value
        System.out.println("Value for key 'Apple': " + hashMap.get("Apple"));  // Output: 4

        // Checking if key or value exists
        System.out.println("Contains key 'Apple': " + hashMap.containsKey("Apple"));  // Output: true
        System.out.println("Contains value 2: " + hashMap.containsValue(2));  // Output: false

        // Iterating over entries
        System.out.println("Entries in hashMap:");
        for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        // Using forEach method (Java 8 and later)
        hashMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

Key Methods of HashMap

  1. put(K key, V value): Associates the specified value with the specified key in this map.
  2. remove(Object key): Removes the mapping for a key from this map if it is present.
  3. get(Object key): Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
  4. containsKey(Object key): Returns true if this map contains a mapping for the specified key.
  5. containsValue(Object value): Returns true if this map maps one or more keys to the specified value.
  6. size(): Returns the number of key-value mappings in this map.
  7. isEmpty(): Returns true if this map contains no key-value mappings.
  8. clear(): Removes all of the mappings from this map.
  9. keySet(): Returns a Set view of the keys contained in this map.
  10. values(): Returns a Collection view of the values contained in this map.
  11. entrySet(): Returns a Set view of the mappings contained in this map.

HashMap vs. Other Map Implementations

  • TreeMap: Implements the NavigableMap interface and uses a tree structure. The keys in a TreeMap are ordered. TreeMap is slower than HashMap for most operations due to the overhead of maintaining the order.
  • LinkedHashMap: Extends HashMap and maintains a linked list of the entries in the map, in the order in which they were inserted. This makes LinkedHashMap slightly slower than HashMap but faster than TreeMap.

Performance Considerations

  • Constant-Time Performance: HashMap provides constant-time performance for basic operations (get and put), assuming the hash function disperses elements properly among the buckets.
  • Load Factor and Initial Capacity: HashMap has a load factor that determines when to rehash the table to increase its capacity. The default load factor is 0.75. The initial capacity and load factor can be specified during the creation of the HashMap.

Conclusion

HashMap is a powerful and flexible implementation of the Map interface, suitable for most use cases where a collection of key-value pairs is needed. Its constant-time performance for basic operations makes it an excellent choice for many scenarios, but it’s important to be aware of the need for a good hash function and appropriate load factor to maintain optimal performance.