Last Updated on January 27, 2023 by Prepbytes
In this article, we will learn about hashmap in java and some important and basic operations on hashmap java and we’ll look at how it works internally.
Hashmap class in java is defined under java.util package in the Collections framework.HashMap class provides the functionality of HashTable Data Structure. HashMap stores the data in form of Key-Value pair. It is denoted as HashMap where K denotes the Key and V denotes the value.
Introduction to HashMap Java
HashMap class is present in Java Collections Framework and is found in java.util package. It offers the rudimentary Java Map interface implementation. It keeps the information in pairs of (Key, Value), and you can access it using an index of a different kind (e.g. an Integer). A key (index) to another object is created using a first object (value). The element of the relevant key will be replaced if you attempt to insert the duplicate key.
HashMap is similar to HashTable class but it lacks synchronization.It also allows null keys. To use HashMap we need to import it from the Collections Framework by using the line
import java.util.HashMap;
Important Points to Know About HashMap in Java
Let us first understand some important points about HashMap Java. Some of the feautures of HashMap are:
- It stores Items in key/value pair.
- No Duplicate Keys are allowed.
- Data doesn’t maintain its order of insertion.
- In HashMap usage of primitive data types is not allowed. We must specify it using Wrapper Classes.
Hierarchy of HashMap in Collections Framework
HashMap Java implements Serializable, Cloneable, and Map Interface. It also extends AbstractMap class.
Syntax of HashMap Java:
The HashMap is defined as follows in Java:
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable
Parameters of HashMap in Java:
The HashMap in Java has two parameters defined below:
- K: It defines the data type of key used. Moreover, the key must be unique for each item.
- V: It defines the data type of values for the keys.
Creating HashMap in Java
To use HashMap in Java, we need to import it from the java.util package using the line given below:
import java.util.HashMap;
Next we
HashMap map = new HashMap();
An example for this is given below:
HashMap map = new HashMap();
Here in this example, we have the key of String datatype and the values are of Integer datatype.
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// create a hashmap
HashMap countries = new HashMap();
// add elements to hashmap
countries.put("India", 8);
countries.put("US", 1);
countries.put("Russia", 3);
System.out.println("HashMap: " + countries);
}
}
Output:
HashMap: {India=8, US=1, Russia=3}
Explanation: In the above example, we have created a HashMap Java named countries and added elements in the map using the put() function.
Constructors in HashMap Java
Each of Java’s four hash map constructors has a public access modifier. These are the constructors:
- HashMap()
- HashMap(int initialCapacity)
- HashMap(int initialCapacity, float loadFactor)
- HashMap(Map map)
Lets delve further into a few other terminologies to gain a better grasp before going into the constructors in detail:
Hashing: Javas HashMap implements the hashing algorithm, which converts object data into a set of representative integer values. Using the method hashCode, one can turn an object into integer form through the process of hashing (). The object class’s hashCode() method returns an integer representation of the object’s memory reference. To store and retrieve any key-value pair, the hash function is therefore used to the key object to determine the bucket’s index.
Capacity: Capacity is defined as the number of buckets stored in the HashMap. The initial Default Capacity of HashMap Java is 16.
Load Factor: The Load Factor is the measure that decides when to increase the capacity of hashmap java. The default value is 75%.
Threshold: The approximate product of the current capacity and load factor is the threshold of a Java hash map.
Rehashing: Recalculating the hash code for already-stored information is known as "rehashing." The Map is rehashed to have almost twice as many buckets as before when the number of entries in the hash table exceeds the threshold value.
Collision: When a hash function returns the same bucket position for two separate keys, it is referred to as a collision.
Constructor 1: HashMap()
It is the default function constructor that builds a HashMap object with a load factor of 0.75 and an initial capacity of 16.
Syntax:
HashMap map = new HashMap();
import java.util.*; class Main { public static void main(String args[]){ HashMap<Integer, String> map = new HashMap<>(); // Adding elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); // Print and display maing of map System.out.println("HashMap: "+ map); } }
Output:
HashMap: {1=one, 2=two, 3=three}
Explanation: In the above example, we create a hashmap using Constructor 1. We have added 3 elements using the put() method. And then we have printed the map.
Constructor 2: HashMap(int initialCapacity)
This constructor build a hashmap object with the specified initial capacity and load factore of 0.75.
Syntax:
HashMap map = new HashMap(int initialCapacity);
import java.util.*; class Main { public static void main(String args[]){ HashMap<Integer, String> map = new HashMap<>(10); // Adding elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); // Print and display maing of map System.out.println("HashMap: "+ map); } }
Output:
HashMap: {1=one, 2=two, 3=three}
Explanation: In the above example, we create a hashmap using Constructor 2 with the initial capacity of 10. We have added 3 elements using the put() method. And then we printed the map
Constructor 3: HashMap(int initialCapacity, float loadFactor)
This constructor builds a hashmap object with the specified initial capacity and specified load factor.
Syntax:
HashMap map = new HashMap(int initialCapacity, float loadFactor);
import java.util.*; class Main { public static void main(String args[]){ HashMap<Integer, String> map = new HashMap<>(3, 0.5f); // Adding elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); // Print and display maing of map System.out.println("HashMap: "+ map); } }
Output:
HashMap: {1=one, 2=two, 3=three}
Explanation: In the above example, we create a hashmap using Constructor 3 with initial capacity of 3 and load factor of 0.3%. We have added 3 elements using the put() method. And then we printed the map.
Constructor 4: HashMap(Map map)
This constructor creates a HashMap Instance with the same mappings as the specified map.
Syntax:
HashMap map = new HashMap(Map map);
import java.util.*; class Main{ public static void main(String args[]){ Map<Integer, String> map1 = new HashMap<>(); // Add Elements using put method map1.put(1, "one"); map1.put(2, "two"); map1.put(3, "three"); HashMap<Integer, String> map2 = new HashMap<Integer, String>(map1); System.out.println("Mappings of HashMap map1 are : " + map1); System.out.println("Mapping of HashMap map2 are : " + map2); } }
Output:
Mappings of HashMap map1 are : {1=one, 2=two, 3=three}
Mapping of HashMap map2 are : {1=one, 2=two, 3=three}
Explanation: In the example shown above, we have created a HashMap map1 and then map2 by initializing the values of map1 to map2. So map1 and map2 will have the same values, capacity, and load factor.
Basic Operations of HashMap Java
Some of the basic operations of HashMap Java are given in detail below:
1. Adding Elements to HashMap Java
We may use the put() method to add an element to the map. However, the Hashmap does not maintain the insertion order. Internally, a unique hash code value is generated for each and every element in the map, and the elements are indexed based on this hash value to increase efficiency.
import java.util.*; class Main{ public static void main(String args[]){ Map<Integer, String> map1 = new HashMap<>(); // Add Elements using put method map1.put(1, "one"); map1.put(2, "two"); map1.put(3, "three"); HashMap<Integer, String> map2 = new HashMap<Integer, String>(map1); System.out.println("Mappings of HashMap map1 are : " + map1); System.out.println("Mapping of HashMap map2 are : " + map2); } }
Output:
HashMap: {1=one, 2=two, 3=three}
Explanation: In the above example, we create a hashmap using Constructor. We have added 3 elements using the put() method. And then we printed the map.
2. Changing Elements in HashMap Java
If we want to update an element after adding it, we can do so by adding it once more using the put() method. The values of the keys can be modified by simply inputting the updated value for the key that needs to be changed because the elements in the map are indexed using the keys.
import java.util.*; class Main{ public static void main(String args[]){ Map<Integer, String> map = new HashMap<>(); // Add Elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); System.out.println("Inital map is : " + map); map.put(2, "updated two"); System.out.println("After Updation map is : "+ map); } }
Output:
Inital map is : {1=one, 2=two, 3=three}
After Updation map is : {1=one, 2=updated two, 3=three}
Explanation: In the above example, we create a hashmap using Constructor. We have added 3 elements using the put() method. And then we printed the map. After that, we updated the value for key “2” to “updated two”. Then print the updated map.
3. Removing an Element in HashMap Java
The remove() method can be used to remove an element from the Map. If there is a mapping for a key in the map, it is removed using this method, which accepts the key value.
import java.util.*; class Main{ public static void main(String args[]){ Map<Integer, String> map = new HashMap<>(); // Add Elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); System.out.println("Inital map is : " + map); map.remove(2); System.out.println("After Updation map is : "+ map); } }
Output:
Inital map is : {1=one, 2=two, 3=three}
After Updation map is : {1=one, 3=three}
Explanation: In the above example, we create a hashmap using Constructor. We have added 3 elements using the put() method. And then we printed the map. After that, we remove the key named “2”. Then print the updated map.
4. Traversing the HashMap
Any Collection Framework structure can be traversed using the Iterator interface. Entry is used to resolve the two distinct types into a format that is compatible with iterators since they only interact with one type of data. The entries of the HashMap are then printed using the next() method.
import java.util.*; class Main{ public static void main(String args[]){ Map<Integer, String> map = new HashMap<>(); // Add Elements using put method map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); // Iterating the map using for-each loop for (HashMap.Entry<Integer, String> m : map.entrySet()) System.out.println("Key: " + m.getKey() + " Value: " + m.getValue()); } }
Output:
Key: 1 Value: one
Key: 2 Value: two
Key: 3 Value: three
Explanation: HashMap.Entry() is used in the above example. Entry(). Entry is an inner class in the map implementation which allows us to iterate over HashMap.entrySet() instead of HashMap.keySet(). So, the HashMap.entrySet() method returns the elements of HashMap.
Some Other Methods in HashMap Java
Some of the other methods already present in Collections Framework are given below:
Method | Description |
---|---|
void clear() | This method is used to remove all the mappings present in the HashMap. |
boolean isEmpty() | This method returns false if the map has no items whereas it returns true if the map is not empty. |
Object clone() | This method returns a shallow copy of the specified HashMap |
Set entrySet() | This method is used to return a collection view of the mappings contained in this map. |
Set keySet() | This method is used to return a set view of the keys contained in this map. |
V put(Object key, Object value) | This method is used to insert an item in the map. |
void putAll(Map map) | This method is used to insert the specified map in the map. |
V putIfAbsent(K key, V value) | This method inserts the specified value with the specified key in the map only if it is not already specified. |
V remove(Object key) | This method is used to delete an entry for the specified key. |
boolean remove(Object key, Object value) | This method removes the specified values with the associated specified keys from the map. |
V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | This method is used to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). |
V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | This method is used to compute its value using the given mapping function, if the specified key is not already associated with a value (or is mapped to null), and enters it into this map unless null. |
V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | This method is used to compute a new mapping given the key and its current mapped value if the value for the specified key is present and non-null. |
boolean containsValue(Object value) | This method returns true if some value equal to the value exists within the map, else return false. |
boolean containsKey(Object key) | This method returns true if some key equal to the key exists within the map, else return false. |
boolean equals(Object o) | This method is used to compare the specified Object with the Map. |
void forEach(BiConsumer<? super K,? super V> action) | This method performs the given action for each entry in the map until all entries have been processed or the action throws an exception. |
V get(Object key) | This method returns the object that contains the value associated with the key. |
V getOrDefault(Object key, V defaultValue) | This method returns the value to which the specified key is mapped, or returns the defaultValue if the map contains no mapping for the key. |
boolean isEmpty() | This method returns true if the map is empty; returns false if it contains at least one key. |
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. |
V replace(K key, V value) | This method replaces the specified value for the specified key. |
boolean replace(K key, V oldValue, V newValue) | This method or function replaces the old value with the new value for the specified key. |
void replaceAll(BiFunction<? super K,? super V,? extends V> function) | This method replaces each entry’s value with the result of invoking the given function on that entry until all of the entries have been processed or the function has thrown an exception. |
Collection< V> values() | This method returns the collection view of the values contained in the Hashmap. |
int size() | The size() method is used to return the number of entries in the HashMap |
Performance of HashMap
Performance of the HashMap java gets affected by the following two factors:
-
Initial Capacity: Capacity is defined as the number of buckets in the Map at the time of creation. The initial Default Capacity of HashMap Java is 16.
-
Load Factor: The Load Factor is the measure that decides when to increase the capacity of hashmap java. The default value is 75%.
Rehashing takes place when the number of hash map entries surpasses the product of LF and capacity. To do this, a new internal array that is twice as large as the first one is formed, and all entries are transferred to new bucket positions in the new array.
Low initial capacity lowers the cost of the physical space but raises the frequency of rehashing. Obviously, rehashing is a highly expensive operation. Therefore, we should specify a very large initial capacity if there are a lot of entries. However, we will incur a cost in iteration time if we make the initial capacity too large. Therefore, a high initial capacity is advantageous for many entries and little to no iteration. A few entries with a lot of iteration benefit from a modest initial capacity.
In the typical scenario, it takes O(1) time to add a value to a hash map. The item is placed after computing the hash function and selecting the bucket. In the worst situation, all of the components will have the same hash value, which requires either traversing the entire bucket list or, in the case of open addressing, probing the entire map until an empty area is discovered. As a result, insertion requires O(n) time in the worst scenario.
Features of HashMap Java
- To access a value, we must know its key. HashMap is known as HashMap because it employs a method called hashing. Faster searches and indexing are facilitated by shorter values.
- Internally, HashSet also makes use of HashMap.
- HashMap Java is a component of java.util package.
- HashMap extends the abstract class AbstractMap, which also offers a rudimentary Map interface implementation.
- In HashMap Java, keys must be unique. Duplicate Keys are not allowed.
- HashMap is unsynchronised
- Items in HashMap don’t maintain the order of insertion.
- It implements the Clonable and Serialisable Interface which provides definitions of K and V.
- Java’s HashMap supports null key and value entries as well. However, there might only be one null key. However, any number of null values could exist and relate to various keys.
Conclusion
We learned how to use a HashMap and its internal workings in this article. HashMap is one of the most often used data structures in Java, along with ArrayList, thus understanding how to use it and how it functions from the inside out is really helpful.