December 31, 2023

Java HashMap With Examples

HashMap in Java is the HashTable implementation of the Map interface and it is part of the Java Collections framework. HashMap class in Java extends AbstractMap class and implements Map, Cloneable and Serializable inerfaces.

HashMap stores its elements as (key, value) pairs and to get a value you will need to provide the key paired with that value. For storing values in HashMap, hashing technique is used where a hash is calculated using the key and that hash value decides in which bucket the value will be stored.

Features of HashMap

Some of the features of the HashMap in Java which are discussed in this post are as follows-

  1. In HashMap values may be duplicate but a key has to be unique. If same key is used then the value will be overwritten.
  2. HashMap uses hashing technique to store values.
  3. HashMap storage is unordered, which means insertion order is not maintained as in the case of ArrayList.
  4. HashMap in Java permits both null values and null keys.
  5. HashMap is not thread safe.
  6. The iterators returned by all of HashMap's "collection view methods" are fail-fast. Which means, if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the Iterator throws a ConcurrentModificationException.

Java HashMap constructors

  • HashMap()- This constructor constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
  • HashMap(int initialCapacity)- This constructor constructs an empty HashMap with the specified initial capacity and the default load factor (0.75).
  • HashMap(int initialCapacity, float loadFactor)- This constructor constructs an empty HashMap with the specified initial capacity and load factor.
  • HashMap(Map<? extends K,? extends V> m)- Constructs a new HashMap with the same mappings as the specified Map.

Initial capacity, load factor and buckets in HashMap

HashMap in Java internally uses an array of type Node to store elements. Where Node<K, V> is an inner class with in HashMap class. You should have clear understanding of the terms initial capacity, load factor and buckets to understand HashMaps better.

  • Capacity- If you don’t specify any capacity while creating HashMap then the array will have default initial capacity of 16. If you use the constructor where initial capacity is also passed then the array will have the specified initial capacity.
  • Bucket- In HashMap concept of bucket is used so each index of array is conceptualized as one bucket. So, total there are 16 buckets. For every (key, value) pair that is added to HashMap a hash is calculated using the key, based on that hash value one of these buckets is chosen to store the element. That way HashMap is able to offer constant time performance for basic operations like get and put.
  • Load factor- Load factor is the threshold for the HashMap storage. Once the threshold is reached the capacity of the HashMap is doubled. Default load factor is 0.75 which means if the 75% of the capacity is reached the HashMap is resized.

Refer HashMap Internal Implementation in Java to get a better understanding of how does HashMap internally works in Java.

Java example creating a HashMap

This example shows how HashMap is created and elements added to it.

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

public class HashMapDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put(null, "Volga");
    carMap.put(null, "Volks Wagon");
    carMap.put("4", null);
    carMap.put("3", "Mini Cooper");
        
    Set<String> carSet =  carMap.keySet();
    for(String key : carSet){
      System.out.println("Key is " + key + " Value is " + carMap.get(key));
    }
  }
}
Output
Key is null Value is Volks Wagon
Key is 1 Value is Audi
Key is 2 Value is BMW
Key is 3 Value is Mini Cooper
Key is 4 Value is null

In the code HashMap of default capacity is created using this statement.

Map<String, String> carMap = new HashMap<String, String>();

All Collection classes are generic now, so you can specify in the beginning itself what type of elements will be stored in the Map. The Map used in this example can store only Strings as both keys and values.

From the output you can see some of the points as already mentioned above.

  1. Insertion order is not maintained in HashMap. Values are not displayed in the order they were inserted.
  2. Two values are inserted with null as key, second insertion overwrites the first one as only one null key is allowed in Java HashMap.
  3. One null value is also inserted.
  4. Two values are inserted with the same key “3”. The second insertion overwrites the first one in case of same key.

Methods in the HashMap class

Here is a list of some of the methods in the HashMap class in Java.

  1. put(K key, V value)- Associates the specified value with the specified key in this map.
  2. putAll(Map<? extends K,? extends V> m)- Copies all of the mappings from the specified map to this map.
  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. remove(Object key)- Removes the mapping for the specified key from this map if present.
  7. clear()- Removes all of the mappings from this map.
  8. entrySet()- Returns a Set view of the mappings contained in 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. size()- Returns the number of key-value mappings in this map.
  12. isEmpty()- Returns true if this map contains no key-value mappings.
  13. compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)- Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).
  14. computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)- If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
  15. computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)- If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.

Java Example removing and replacing elements from HashMap

public class HashMapDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
    // removing element
    carMap.remove("2");
        
    // replacing element
    carMap.replace("3", "Land Rover");
    Set<String> carSet =  carMap.keySet();
    for(String key : carSet){
        System.out.println("Key is " + key + " Value is " + carMap.get(key));
    }
  }
}
Output
Key is 1 Value is Audi
Key is 3 Value is Land Rover
Key is 4 Value is Mini Cooper

Example with computeIfPresent and computeIfAbsent using lambdas

public class HashMapDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
    // returns value for new key
    carMap.computeIfAbsent("5", k -> {return "Land Rover";});
    // change value for existing key
    carMap.computeIfPresent("4", (String k, String v) -> {
    if (carMap.get(k).equals("Mini Cooper")){
        return "Mazda";} 
    else
        return v;});
        
    Set<String> carSet =  carMap.keySet();
    for(String key : carSet){
      System.out.println("Key is " + key + " Value is " + carMap.get(key));
    }
  }
}
Output
Key is 1 Value is Audi
Key is 2 Value is BMW
Key is 3 Value is Jaguar
Key is 4 Value is Mazda
Key is 5 Value is Land Rover

Java HashMap iterator example

You can’t directly use an iterator with HashMap. You will have to get the collection view of the Map and then iterate it. The iterators returned by the iterator methods are fail-fast. If the Map is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the Iterator throws a ConcurrentModificationException.

Refer Different Ways to Iterate a HashMap in Java to see your options for iterating a HahsMap.

Let’s try to clarify it with an example. In the code while iterating the HashMap after getting it’s set view using keySet() we’ll try to remove an element using the HashMap’s remove() method not the iterator’s remove method. All these methods like entrySet() or keySet() are fail-fast. Which means, if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the Iterator throws a ConcurrentModificationException.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
        
    Set<String> carSet =  carMap.keySet();
    Iterator<String> itr = carSet.iterator();
    while (itr.hasNext()) {
      String key = itr.next();
      System.out.println("Key is " + key + " Value is " + carMap.get(key));    
      // removing value using HashMap's remove method
      if(key.equals("2")){
          carMap.remove(key);
      }
    }
  }
}
Output
Key is 1 Value is Audi
Key is 2 Value is BMW
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(Unknown Source)
	at java.util.HashMap$KeyIterator.next(Unknown Source)
	at com.knpcode.HashMapDemo.main(HashMapDemo.java:22)

As you can see ConcurrentModificationException exception is thrown as you are trying to structurally modify the HashMap while it is iterated using an iterator.

Using iterator’s remove method

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapDemo {
  public static void main(String[] args) {
    // Creating HashMap
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    carMap.put("4", "Mini Cooper");
        
    Set<String> carSet =  carMap.keySet();
    Iterator<String> itr = carSet.iterator();
    while (itr.hasNext()) {
      String key = itr.next();
      System.out.println("Key is " + key + " Value is " + carMap.get(key));    
      // removing value using HashMap's remove method
      if(key.equals("2")){
          itr.remove();
      }
    }
        
    System.out.println("** After element removal **");
    for(String key : carMap.keySet()){
      System.out.println("Key is " + key + " Value is " + carMap.get(key));
    }
  }
}
Output
Key is 1 Value is Audi
Key is 2 Value is BMW
Key is 3 Value is Jaguar
Key is 4 Value is Mini Cooper
** After element removal **
Key is 1 Value is Audi
Key is 3 Value is Jaguar
Key is 4 Value is Mini Cooper

HashMap is not threadsafe

HashMap in Java is not threadsafe. If you are using HashMap in multithreaded environment where instance of HashMap is shared among many threads, you should synchronize it externally. In order to synchronize Map you can use Collections.synchronizedMap() method which returns a synchronized Map backed by the specified map.

As example-
Map<String, String> tempMap = Collections.synchronizedMap(carMap);

That's all for the topic Java HashMap With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment