This Java HashMap Tutorial Explains What is a HashMap in Java and How to use it. It includes How to Declare, Initialize, Iterate, Implement & Print HashMap:
HashMap in Java is a collection based on Map and consists of key-value pairs. A HashMap is denoted by < Key, Value > or < K, V >. A HashMap element can be accessed using a Key i.e. we must know the key to access the HashMap element.
A HashMap uses a technique called “Hashing”. In hashing, a longer string is converted into a shorter string by applying some algorithm or ‘hash function’. A string is converted to a shorter string as it helps in searching that is faster. It is also used for efficient indexing.
=> Visit Here For The Exclusive Java Training Tutorial Series.
Table of Contents:
HashMap In Java
A HashMap is similar to HashTable with a difference that the HashMap is not synchronized and allows null values for key and value.
Some of the important characteristics of HashMap are given below:
- HashMap is implemented in Java in the “Hashmap” class that is a part of java.util package.
- HashMap class inherits from the class “AbstractMap” that partially implements the Map interface.
- HashMap also implements ‘cloneable’ and ‘serializable’ interfaces.
- HashMap permits duplicate values but does not permit duplicate keys. HashMap also allows multiple null values but a null key can be only one.
- HashMap is unsynchronized and also does not guarantee the order of the elements.
- Java HashMap class has an initial capacity of 16 and the default (initial) load factor is 0.75.
How To Declare A HashMap In Java?
A HashMap in Java is a part of the java.util package. Hence, if we need to use HashMap in our code, we first need to import the implementation class using one of the following statements:
import java.util.*;
OR
import java.util.HashMap;
The general declaration of HashMap class is:
public class HashMap < K,V > extends AbstractMap<K,V> implements Map< K,V >, Cloneable, Serializable
Here, K=> type of keys present in the map
V=> type of values mapped to the keys in the map
Create A HashMap
A HashMap in Java can be created as follows:
import java.util.HashMap; HashMap < Integer, String > cities_map = new HashMap <Integer, String> ();
The above statement first includes the HashMap class in Java. Then in the next statement, we create a HashMap named ‘cities_map’ with key type as Integer and Values as String.
Once the HashMap is created, we need to initialize it with values.
How To Initialize Hash Map?
We can initialize the HashMap using the put method by putting some values in the map.
The below program shows the initialization of HashMap in Java.
import java.util.*; class Main{ public static void main(String args[]){ //create a HashMap and print HashMap<Integer,String> colorsMap=new HashMap<Integer,String>(); System.out.println("Initial Map: "+colorsMap); //put some initial values into it using put method colorsMap.put(100,"Red"); colorsMap.put(101,"Green"); colorsMap.put(102,"Blue"); //print the HashMap System.out.println("After adding elements:"); for(Map.Entry m:colorsMap.entrySet()){ System.out.println(m.getKey()+" "+m.getValue()); } } }
Output:
Initial Map: {}
After adding elements:
100 Red
101 Green
102 Blue
How Does A HashMap Work Internally?
We know that HashMap is a collection of key-value pairs and it makes use of a technique called ‘Hashing’. Internally, the HashMap is an array of nodes. HashMap makes use of array and LinkedList for storing key-value pairs.
Given below is a structure of a node of HashMap that is programmatically represented as a class.
As seen from the node representation above, a node has a structure similar to a linked list node. An array of these nodes is called Bucket. Each bucket may not have the same capacity and it can have more than one node as well.
The performance of HashMap is influenced by two parameters:
(i) Initial Capacity: Capacity is defined as the number of buckets in the HashMap. Initial Capacity is defined as the capacity of the HashMap object when it is created. The capacity of the HashMap is always multiplied by 2.
(ii) LoadFactor: LoadFactor is the parameter that measures when rehashing – increasing the capacity, will be done.
Note that if the capacity is high, the load factor will be small as no rehashing will be required. Similarly, when capacity is low, the load factor will be high as we will need to rehash frequently. Thus we should exercise care to carefully choose these two factors to design an efficient hashMap.
How To Iterate A HashMap?
The HashMap needs to be traversed to manipulate or print the key-value pairs.
There are two ways in which we can traverse or iterate through the HashMap.
- Using for loop
- Using the while loop and the iterator.
The Java program below shows the implementation of both these methods.
First, we retrieve the set of entries from HashMap using the entrySet method and then we traverse the set using for loop. Then we print the key-value pairs using the getKey () and getValue () methods respectively.
To traverse the HashMap using a while loop, we first set an iterator for the HashMap and then access the key-value pairs using the iterator.
import java.util.*; public class Main{ public static void main(String [] args) { //create a HashMap and initialize it HashMap<Integer, String> cities_map = new HashMap<Integer, String>(); cities_map.put(10, "MUM"); cities_map.put(1, "DL"); cities_map.put(20, "PUN"); cities_map.put(7, "GOA"); cities_map.put(3, "HYD"); //print using for loop System.out.println("HashMap using for Loop:"); System.out.println("\tKEY\tVALUE"); for (Map.Entry mapSet : cities_map.entrySet()) { System.out.println("\t"+mapSet.getKey() + "\t" + mapSet.getValue()); } //print using while loop with iterator System.out.println("HashMap using while Loop:"); System.out.println("\tKEY\tVALUE"); Iterator iterator = cities_map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry mapSet2 = (Map.Entry) iterator.next(); System.out.println("\t"+mapSet2.getKey() + "\t" + mapSet2.getValue()); } } }
Output:
HashMap using for Loop:
KEY VALUE
1 DL
3 HYD
20 PUN
7 GOA
10 MUM
HashMap using while Loop:
KEY VALUE
1 DL
3 HYD
20 PUN
7 GOA
10 MUM
Print A Hash Map
Let’s see another example of printing the hashMap using the foreach loop shown in the below program.
import java.util.HashMap; public class Main { public static void main(String[] args) { // create a HashMap and initialize HashMap<String, Integer> colors = new HashMap<String, Integer>(); colors.put("Red", 1); colors.put("Orange", 5); colors.put("Magenta", 8); //print the HashMap System.out.println("HashMap contents:"); System.out.println("\tKEY\tVALUE"); for (String i : colors.keySet()) { System.out.println("\t" + i + "\t" + colors.get(i)); } } }
Output:
HashMap contents:
KEY VALUE
Red 1
Magenta 8
Orange 5
HashMap Constructor/Methods In Java
The below tables show the constructors and methods provided by the HashMap class in Java.
Constructors
Constructor Prototype | Description |
---|---|
HashMap () | Default constructor. |
HashMap ( Map < ? extends K,? extends V > m) | Creates a new HashMap from the given map object m. |
HashMap ( int capacity) | Creates a new HashMap with the initial capacity given by argument ‘capacity’. |
HashMap ( int capacity, float loadFactor ) | Creates a new HashMap using the values of capacity and loadFactor provided by the constructor. |
Methods
Method | Method Prototype | Description |
---|---|---|
clear | void clear () | Clears all the mappings in the HashMap |
isEmpty | boolean isEmpty () | Checks if the HashMap is empty. Returns true if yes. |
clone | Object clone () | Returns a shallow copy without cloning the keys and values mappings in the HashMap. |
entrySet | Set entrySet () | Returns mappings in the HashMap as a collection |
keyset | Set keySet () | Returns a set of Keys in the HashMap. |
put | V put ( Object key, Object value) | Inserts a key-value entry in the HashMap. |
putAll | void putAll ( Map map) | Inserts specified ‘map’ elements in the HashMap. |
putIfAbsent | V putIfAbsent (K key, V value) | Inserts given key-value pair in the HashMap if it is not already present. |
remove | V remove (Object key) | Delete an entry from the HashMap for the given key. |
remove | boolean remove (Object key, Object value) | Deletes the given key-value pair from the HashMap. |
compute | V compute (K key, BiFunction < ? super K,? super V,? extends V > remappingFunction) | Computes mapping using ‘remappingfunction’ for the given key and its current value or null value. |
Method | Method Prototype | Description |
computeIfAbsent | V computeIfAbsent (K key, Function < ? super K,? extends V > mappingFunction) | Computes the mapping using the ‘mappingFunction’ and inserts key-value pairs if it not already present or is null. |
computeIfPresent | V computeIfPresent (K key, BiFunction remappingFunction) | Computes a new mapping using the ‘remappingFunction’ given the key if the key is already present and non-null. |
containsValue | boolean containsValue ( Object value) | Checks if the given value exists in the HashMap and returns true if yes. |
containsKey | boolean containsKey (Object key) | Checks if the given key is present in the HashMap and returns true if yes. |
equals | boolean equals (Object o) | Compares given object with the HashMap. |
forEach | void forEach (BiConsumer < ? super K,? super V > action) | Executes given ‘action’ for each of the entries in the HashMap. |
get | V get (Object key) | Returns the object containing the given key with the associated value. |
getOrDefault | V getOrDefault (Object key, V defaultValue) | Returns the value to which the given key is mapped. If not mapped then returns the default value. |
isEmpty | boolean isEmpty () | Checks if the HashMap is empty. |
merge | V merge (K key, V value, BiFunction < ? super V,? super V,? extends V > remappingFunction) | Checks if the given key is null or not associated with value and then associates it with a non-null value using remappingFunction. |
replace | V replace (K key, V value) | Replaces the given value for the specified key. |
replace | boolean replace (K key, V oldValue, V newValue) | Replaces the old value of the given key with the new value |
replaceAll | void replaceAll (BiFunction < ? super K,? super V,? extends V > function) | Executes the given function and replaces all values in the HashMap with the function result. |
values | Collection < V > values() | Returns the collection of values present in the HashMap. |
size | int size () | Returns the size of the number of entries in the HashMap. |
Hashmap Implementation
Next, we will implement most of these functions in a Java program to understand their working better.
The following Java program shows an implementation of HashMap in Java. Note that we have used most of the methods that we discussed above.
import java.util.*; public class Main { public static void main(String args[]) { HashMap<Integer, String> hash_map = new HashMap<Integer, String>(); hash_map.put(12, "Leo"); hash_map.put(2, "Seville"); hash_map.put(7, "Lacy"); hash_map.put(49, "Lily"); hash_map.put(3, "Dillon"); System.out.println("HashMap contents:"); System.out.println("\tKEY\tVALUE"); //display HashMap contents Set setIter = hash_map.entrySet(); Iterator map_iterator = setIter.iterator(); while(map_iterator.hasNext()) { Map.Entry map_entry = (Map.Entry)map_iterator.next(); System.out.println("\t"+ map_entry.getKey() + "\t" + map_entry.getValue()); } //get value for the given key String var= hash_map.get(2); System.out.println("Value at index 2 is: "+var); //delete value given the key hash_map.remove(3); System.out.println("Hashmap after removal:"); System.out.println("\tKEY\tVALUE"); Set iter_set = hash_map.entrySet(); Iterator iterator = iter_set.iterator(); while(iterator.hasNext()) { Map.Entry mentry = (Map.Entry)iterator.next(); System.out.println("\t"+mentry.getKey() + "\t" + mentry.getValue() ); } } }
Output:
HashMap contents:
KEY VALUE
49 Lily
2 Seville
3 Dillon
7 Lacy
12 Leo
Value at index 2 is: Seville
Hashmap after removal:
KEY VALUE
49 Lily
2 Seville
7 Lacy
12 Leo
Sort HashMap In Java
In Java, HashMap does not preserve the order. Hence we need to sort the elements in the HashMap. We can sort the elements in the HashMap either based on keys or values. In this section, we will discuss both sorting approaches.
Sort HashMap By Keys
import java.util.*; public class Main { public static void main(String[] args) { //create and initialize a HashMap HashMap<Integer, String> colors_map = new HashMap<Integer, String>(); colors_map.put(9, "Magenta"); colors_map.put(11, "Yellow"); colors_map.put(7, "Cyan"); colors_map.put(23, "Brown"); colors_map.put(5, "Blue"); colors_map.put(3, "Green"); colors_map.put(1, "Red"); //print the unsorted HashMap by getting a set and using iterator System.out.println("Unsorted HashMap:"); Set set = colors_map.entrySet(); Iterator iterator = set.iterator(); while(iterator.hasNext()) { Map.Entry me = (Map.Entry)iterator.next(); System.out.print(me.getKey() + ": "); System.out.println(me.getValue()); } //create a treemap from given HashMap so that the keys are sorted Map<Integer, String> map = new TreeMap<Integer, String>(colors_map); System.out.println("HashMap Sorted on keys:"); //print the sorted HashMap Set set2 = map.entrySet(); Iterator iterator2 = set2.iterator(); while(iterator2.hasNext()) { Map.Entry me2 = (Map.Entry)iterator2.next(); System.out.print(me2.getKey() + ": "); System.out.println(me2.getValue()); } } }
Output:
Unsorted HashMap:
1: Red
3: Green
5: Blue
7: Cyan
23: Brown
9: Magenta
11: Yellow
HashMap Sorted on keys:
1: Red
3: Green
5: Blue
7: Cyan
9: Magenta
11: Yellow
23: Brown
In the above program, we see that once the hashmap is defined and populated with values, we create a treemap from this hashmap. As the hashmap is converted to a treemap, its keys are automatically sorted. Thus when we display this treemap, we get the sorted map on keys.
Sort HashMap By Values
For sorting a HashMap according to values, we first convert the hashmap to a LinkedList. Then we use the Collections.sort method along with the comparator to sort the list. This list is then converted back to HashMap. The sorted HashMap is then printed.
import java.util.*; public class Main { public static void main(String[] args) { //Create and initialize the HashMap HashMap<Integer, String> colors_map = new HashMap<Integer, String>(); colors_map.put(5, "B"); colors_map.put(11, "O"); colors_map.put(3, "I"); colors_map.put(13, "R"); colors_map.put(7, "G"); colors_map.put(1, "V"); colors_map.put(9, "Y"); //print the HashMap using iterator after converting to set System.out.println("Unsorted HashMap:"); Set set = colors_map.entrySet(); Iterator iterator = set.iterator(); while(iterator.hasNext()) { Map.Entry map_entry = (Map.Entry)iterator.next(); System.out.print(map_entry.getKey() + ": "); System.out.println(map_entry.getValue()); } //call sortByValues method that returns a sorted Map. Map<Integer, String> c_map = sortByValues(colors_map); System.out.println("HashMap sorted on values:"); //print the sorted HashMap Set set2 = c_map.entrySet(); Iterator iterator2 = set2.iterator(); while(iterator2.hasNext()) { Map.Entry map_entry2 = (Map.Entry)iterator2.next(); System.out.print(map_entry2.getKey() + ": "); System.out.println(map_entry2.getValue()); } } private static HashMap sortByValues(HashMap hash_map) { //create a LinkedList from HashMap List list = new LinkedList(hash_map.entrySet()); // use Collections.sort method with Comparator to sort the list Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); //create a HashMap from linkedlist which preserves the order HashMap sortedHashMap = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); sortedHashMap.put(entry.getKey(), entry.getValue()); } return sortedHashMap; } }
Output:
Unsorted HashMap:
1: V
3: I
5: B
7: G
9: Y
11: O
13: R
HashMap sorted on values:
5: B
7: G
3: I
11: O
13: R
1: V
9: Y
Concurrent HashMap In Java
In a normal HashMap, we will not be able to modify the elements at runtime or while iteration is being performed.
The implementation of a concurrent map is shown below:
import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class Main { public static void main(String[] args) { //declare and initialize ConcurrentHashMap Map<String,String> cCMap = new ConcurrentHashMap<String,String>(); cCMap.put("1", "10"); cCMap.put("2", "10"); cCMap.put("3", "10"); cCMap.put("4", "10"); cCMap.put("5", "10"); cCMap.put("6", "10"); //print the initial ConcurrentHashMap System.out.println("Initial ConcurrentHashMap: "+cCMap); //define the iterator over the keys of ConcurrentHashMap Iterator<String> it = cCMap.keySet().iterator(); //change one of the keys using iterator while(it.hasNext()){ String key = it.next(); if(key.equals("3")) cCMap.put(key+"c_map", "c_map"); } //print the changed ConcurrentHashMap System.out.println("\nConcurrentHashMap after iterator: "+cCMap); } }
Output:
Initial ConcurrentHashMap: {1=10, 2=10, 3=10, 4=10, 5=10, 6=10}
ConcurrentHashMap after iterator: {1=10, 2=10, 3=10, 4=10, 5=10, 6=10, 3c_map=c_map}
Note that if we had carried out the same operation with HashMap, then it would have thrown ConcurrentModificationException.
Java Map Vs HashMap
Let’s tabularize some of the differences between Map and HashMap in Java.
Map | HashMap |
---|---|
It is an abstract interface. | Is an implementation of Map interface. |
The interface needs to be implemented by other classes for its functionality to be available. | Is a concrete class and class objects can be created to get the functionality. |
Map interface implementation like TreeMap does not allow null values. | Allows null values and keys. |
TreeMap does not allow duplicate values. | It can have duplicate values. |
A natural ordering of objects is maintained. | No input order is maintained in HashMap. |
Frequently Asked Questions
Q #1) Why is HashMap used in Java?
Answer: HashMap being the collection of key-value pairs assists in searching the data based on the key alone. Also as it uses hashing techniques, it provides an efficient lookup of data.
Q #2) How do you create a hash map?
Answer: A HashMap can be created by instantiating the ‘HashMap’ class of the java.util package. A hashMap with keys of type integer and values of type string can be created as follows:
HashMap<Integer,String> myMap=new HashMap<Integer,String>();
Q #3) Is HashMap ordered in Java?
Answer: No, the HashMap is not ordered in Java. It is not used in Java for that purpose but is used for storing elements in key-value pairs.
Q #4) Is HashMap thread-safe?
Answer: NO, the hashMap is not thread-safe in Java.
Q #5) Which is faster HashMap or ConcurrentHashMap?
Answer: HashMap is faster than ConcurrentHashMap. The reason is that HashMap operates on only one thread usually, thus its performance is good. Concurrent HashMap, however, as the name suggests, is concurrent and can work simultaneously on multiple threads.
Conclusion
In this tutorial, we understood the working of HashMap along with another variation of HashMap called ConcurrentHashMap. We have seen constructors, methods, and examples of HashMap. We also discussed ConcurrentHashMap along with its example.
In our upcoming tutorials, we will learn more about Java Collections.
=> Check Here To See A-Z Of Java Training Tutorials Here.