In my previous blog introduced the hashmap and explained how it works internally with the get() and put() methods. This blog will continue the previous one and cover various methods used in the hashmap.
Hashmap has several methods for carrying out actions including adding, retrieving the data, updating, deleting, and more. These methods provide essential functionalities for adding, retrieving, removing, and iterating through the elements in a hashmap, enabling efficient manipulation and management of key-value pairs.
Along with this methods ,later Java 8, has introduced a few new functions in the hashmap which I have explained later in this blog with examples.
Let’s see an overview of several Hashmap functions along with the code. Most of the methods will be straightforward .
put(K key,V value)Inserts an entry in the map. It allows to insertion of multiple null values and one null key.The key must be unique if the map previously contained a mapping for the key the old value is replaced.
putAll(Map map) Inserts a specified map in the map.
remove(K key): Deletes the entry for the specified key from the map if present.
isEmpty() This method returns true if the map does not contain any key-value mappings.
get(Key K) This method returns the corresponding value of the specified key from the hashmap or returns “null” if the map contains no mapping for the key.
keyset() Returns the set view of all the keys of the hashmap.
Values() Returns set of the values contained in the hashmap.
entrySet() Returns the set view of the mappings in the hashmap.
Boolean remove(object key, object value) Removes the entry for the specified key only if it is mapped to the specified value and returns true if the value is removed.
replace(K key, V value) Replace the specified key with the specified value.
containsKey(K Key) Check if the map contains a mapping for the specified key and return true if it has a mapping.
contains value(V Value) Returns true if the map maps one or more keys to the specified value
hashcode() This method returns the hashcode of the specified key.
equals(object o) This method compares the two hashmaps by key-value pairs. It means both hashmap instances must have the same key-value pairs and of the same size.
Clone()
This method returns the shallow copy of the hashmap instance. Here shallow copy means keys and values are not copied. Instead references to keys/ values are copied.
Example: HashMap<Integer,String>cloned_map=(HashMap<Integer,String>)demo_map.clone();
In the above expression:demo_map.clone()--àReturns a copy of the object
HashMap<Integer, String>-à converts the object returned by clone() into a hashmap of Integer type key and String type Values.
Clear() Removes all the mapping from the given map.The map will be empty after this call returns.
Have a look at the below Example program for the different methods of hashmap:
package collections;
import java.util.HashMap;
public class Hashmap_Concepts {
public static void main(String[] args) {
HashMap<Integer ,String> demo_map=new HashMap<Integer ,String>();
HashMap<Integer ,String> demo_map1=new HashMap<Integer ,String>();
//put(key,value)
demo_map.put(1,"Wonka");
demo_map.put(2,"Union");
demo_map.put(3,"Dune");
demo_map.put(4,"Up");
demo_map.put(5,"Sonic");
demo_map.put(6,"Minions");
demo_map.put(7, null);
demo_map.put(null,"pokemon");
//To find the hashcode
System.out.println("Hashcode for the key 1:"+demo_map.get(1).hashCode());
//size()
System.out.println("The size of the hashmap:"+demo_map.size());
//isEmpty()
System.out.println("The value of isempty()for"+","+"demo_new :"+demo_map1.isEmpty());
System.out.println("The value of isempty()for"+","+"demo_map: "+demo_map.isEmpty());
//putAll(Map map)
demo_map1.putAll(demo_map);
System.out.println("Items in demo_map1:"+demo_map1);
//remove(key)
boolean has_removed = demo_map.remove(7,"null");
System.out.println("Updated entries after remove():"+has_removed);
//keyset()
System.out.println("keys:"+demo_map.keySet());
//Values()
System.out.println("Values:"+demo_map.values());
//entryset()
System.out.println("Set View:"+demo_map.entrySet());
//get(key)
System.out.println("Hashmap value with Key 3:"+demo_map.get(3));
//replace(key,value)
demo_map.replace(1,"Mulan");
System.out.println("After updating the value of the key:"+demo_map);
//containsKey(key)
boolean has_key=demo_map.containsKey(3);
System.out.println("Hashmap conatains a key 3 ? "+has_key);
//containsValue(value)
boolean has_value=demo_map.containsValue("Sonic");
System.out.println("Hashmap conatains a value sonic ?"+has_value);
//equals(object o)
System.out.println("The Equality betwen 2 hashmaps:"+demo_map.equals(demo_map1));
//clone()
HashMap<Integer,String>cloned_map=(HashMap<Integer,String>)demo_map.clone();
System.out.println("Cloned Hashmap:"+cloned_map);
//clear()
demo_map1.clear();
System.out.println("Hashmap after clear():"+demo_map1);
}
}
New HashMap Methods introduced in Java 8 in detail:
1)getOrDefault(K key,V default value) : Returns the value of the specified key or returns the default value if the given key is not mapped.
public class Hashmap_NewFunctions {
public static void main(String[] args) {
HashMap<Integer,String >products_code= new HashMap<Integer,String>();
products_code.put(100,"Books");
products_code.put(101,"Toys");
products_code.put(102,"Pens");
products_code.put(103,"Bags");
//11.getOrDefault
String value1=products_code.getOrDefault (102, "Not Found");
String value2=products_code.getOrDefault(200,"Not Found");
//Mapping for the key is not present in hashmap
System.out.println("Value for the key 102:"+value1);
//Mapping for the key present in hashmap
System.out.println("Value for the key 200 :"+value2);
}}
2)putIfAbsent(K Key, V Value)
Inserts the entry only when the given key is not present in the hashmap. If the specified key is already available in the hashmap then the specified value will not be inserted to that key.
Example:
//putIfAbsent(Key,Value)
System.out.println("Product list before using putIfAbsent()");
products_code.putIfAbsent(102,"Pencils");
System.out.println("Updated list after using putifabsent():"+products_code);
products_code.putIfAbsent(104,"Pencils");
System.out.println("Updated list after using putifabsent():"+products_code);
Output:
In the above code , the key 102 is already associated with the value so putIfAbsent () does not add the mapping {102,"Pencils"} to the Hashmap, whereas the key 104 is not having any entry so it will be added to the hashmap.
3)void replaceAll(BiFunction<?super k, ?super V,?extendsV> function):
This will replace each entry value with the result of the function after it has been processed
Example: Here in the below snippet trying to change all the values to the upper case.
//replaceall()
products_code.replaceAll((key,value)->value.toUpperCase());
System.out.println("Updated hashmap after using replaceall():"+products_code);
In this example it replaces each entry values of the hahsmp with result of invoking the given function , which is to convert the values into upper case .
4)merge(K key , V value ,BiFunction<?super k, ?super V,?extendsV> remappingFunction)
If the specified key is already associated with the value, then this method replaces the old value with the new result of the specified function. OR if the specified key is not mapped to any value or if the key is null then it will be mapped with the given non-null value.
//merge()
products_code.merge(107,"ArtSupplies",(oldvalue, newvalue) -> oldvalue+newvalue);
System.out.println("Updated hashmap after merge():"+products_code);
products_code.merge(101,"Puzzle",(oldvalue,newvalue)->oldvalue+"/"+newvalue);
System.out.println("Updated hashmap after merge():"+products_code);
In the above example as the entry{107, "ArtSupplies"} is not present in hashmap the merge() inserts the entry, whereas the key 101 is already associated with a value, so the old value is replaced by the value returned from remapping function which is Toys/Puzzle.
5)compute(K key, BiFunction<?super k, ?super V,?extendsV> remappingFunction)
Computes the mapping for the specified key and its current mapped value. Returns null if there is no mapping.
//compute()
System.out.println("Original values in hashmap:"+products_code);
products_code.compute(100,(key,value) ->value.concat(" "+"and"+" "+"NOTEBOOKS"));
System.out.println("After update using compute() values in hashmap are:"+products_code);
In this example the key 100 is present , the value associated with 100 will be replaced by the computed value from the remapping function.
6)computeIfPresent(K key, BiFunction<?super k, ?super V,?extendsV> remappingFunction)
This will update the computed value for the given key only the specified key is available in the hashmap.
//computeIfPresent()
System.out.println("Before using computeIfPresent()"+product_price);
product_price.computeIfPresent("Craftsupplies",(key,value)->value+value*20/100);
System.out.println("The value of Craftsupplies after vat:"+product_price.get("Craftsupplies"));
System.out.println("Updated hashmap:"+product_price);
In this example the price for the craftsupplies has updated with 20% vat, which is the new value returned by the mapping function because the key craftsupplies is already mapped to a value in the hashmap.
7) computeIfAbsentK key, BiFunction<?super k, ?super V,?extendsV> remappingFunction)
This will check if the specified key is associated with any value , if not associated with any value then it attempts to compute the value on given mapping functions and enter in into the map. If the mapping function returns null then no mapping will be recorded.
//computeIfAbsent()
product_price.computeIfAbsent("Pens",key->200);
System.out.println("Updated hashmap after using computeIfAbsent():"+product_price);
product_price.computeIfAbsent("Pencils",key->400);
System.out.println("Updated hashmap after using computeIfAbsent():"+product_price);
In the above code, it will check if the key pens have an entry, as it is already associated with the value 100, so this will not update the computed value on the key pens, whereas pencils are not associated with any values so the 400 value is associated with the key pencils.
8) for Each(BiConsumer<? Super K, ? super V> action)
This method performs the action specified by lambda expression for each entry of the hashmap.
// Iterate the hashmap through for each and lambda
System.out.println("Iterating by using the for each and lambda before adding vat ");
product_price.forEach((k,v)-> System.out.println("Key = " +k+ " and Value = " + v));
System.out.println("Added Vat for the products :");
product_price.forEach((key,value) ->
{
value=value+value*20/100;
System.out.println(key+":"+value+" ");
});
Hashmap is one of the most frequently used data structures in Java. They help to access the element faster because it retrieves and inserts the element based on the key and the average time complexity to insert and retrieve the element is O(n). And regarding the memory it automatically resizes when it reaches the threshold.
Despite having many pros it comes with a limitation like performance degradation and to have a high performance a good implementation of hashcode(), equals() methods along with the hash function is required. In some cases when a collision occurs it has a worst-case time complexity.
Hashmaps are not synchronized(not threadsafe) as multiple threads can modify their structure while accessing thus they are not suitable for multithreaded environments. So we must synchronize externally to prevent concurrent modifications. I will be covering these in my next blog.
Thank you all for reading till the end. Happy Learning!!