Map
interface. It stores entry in key-value pairs. It maps keys to values. It is one of the most used Collection.Table of Contents
- Java HashMap
- HashMap Constructors
- Add key-value pairs to HashMap
- Remove entries from HashMap
- Important HashMap methods
- Write declarative style code with HashMap
- Get entrySet(), keySet() and values() from HashMap
- Iterate over HashMap
- Storing Custom objects as Key
- Sort HashMap in java
- is HashMap thread-safe?
- How HashMap works internally
- Java 8 HashMap update
- Java HashMap tutorial
- Conclusion
Java HashMap
HashMap
implementsMap
an interface that maps a key to value.- It is not synchronized and is not thread-safe.
- Duplicate keys are not allowed
- One
null
key and multiplenull
values are allowed - It is the unordered collection and does not give a guarantee for any specific order of elements.
Yes, Just to make things more obvious, HashMap implements Map interface again and there is nothing wrong in implementing interface again.You don’t have to go through class Hierarchy to find it out that HashMap implements Map interface.
HashMap Constructors
Java HashMap class has four constructors
public HashMap()
: This is the default constructor and used mostly. It creates an empty HashMap with default initial capacity of 16 and load factor 0.75.
public HashMap(int initialCapacity)
: This constructor is used to specify the initial capacity of HashMap and default load factor 0.75.
public HashMap(int initialCapacity,float loadFactor)
: This constructor is used to specify initial capacity of the HashMap and load factor. In most of the scenarios, you should avoid using this constructor unless you are sure about this as load factor 0.75 provides a good tradeoff between time and space.
public HashMap(Map<? extends K,? extends V> m)
: This constructor is used when you want to create HashMap from some other Map such as TreeMap or LinkedHashMap.
Add key-value pairs to HashMap
We can use put()
method to add entries to HashMap
.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package org.arpit.java2blog; package org.arpit.java2blog; import java.util.HashMap; public class HashMapBuiltMain { public static void main(String[] args) { HashMap<Integer, String> employeeHashmap = new HashMap<Integer, String>(); // Putting key-values pairs in HashMap employeeHashmap.put(1, "Arpit"); employeeHashmap.put(2, "John"); employeeHashmap.put(3, "Martin"); employeeHashmap.put(4, "Vaibhav"); System.out.println(employeeHashmap); } } |
When you run above program, you will get below output
What if you want to add entries only if it is not already present in HashMap?
You can use putIfAbsent()
the method in this scenario.
Remove entries from HashMap
There are two ways to remove entries in HashMap.
remove(Object key)
: It removes key from HashMapremove(Object key,Object value)
: It removes key if value is same as passed parameter value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package org.arpit.java2blog.HashMap; import java.util.HashMap; public class HashMapRemoveMain { public static void main(String[] args) { HashMap<String, Integer> vehicleMaxSpeedMap = new HashMap<String, Integer>(); // Putting key-values pairs in HashMap vehicleMaxSpeedMap.put("Bike", 120); vehicleMaxSpeedMap.put("Car", 220); vehicleMaxSpeedMap.put("Truck", 160); vehicleMaxSpeedMap.put("Activa", 140); System.out.println(vehicleMaxSpeedMap); // Remove truck key Integer speed = vehicleMaxSpeedMap.remove("Truck"); System.out.println("==============================="); System.out.println("Vehicle Truck with max speed "+speed+" removed from HashMap"); System.out.println(vehicleMaxSpeedMap); System.out.println("================================"); // Remove Car if value is 200 boolean isCarRemoved = vehicleMaxSpeedMap.remove("Car",200); // Car key won't be removed as associated value is 220 System.out.println("Did car removed from HashMap: "+isCarRemoved); System.out.println(vehicleMaxSpeedMap); System.out.println("==============================="); // Remove Car if value is 200 boolean isActivaRemoved = vehicleMaxSpeedMap.remove("Activa",140); // Activa key will be removed as associated value is 140 System.out.println("Did activa removed from HashMap: "+isActivaRemoved); System.out.println(vehicleMaxSpeedMap); System.out.println("==============================="); } } |
===============================
Vehicle Truck with max speed 160 removed from HashMap
{Car=220, Activa=140, Bike=120}
================================
Did car removed from HashMap: false
{Car=220, Activa=140, Bike=120}
===============================
Did activa removed from HashMap: true
{Car=220, Bike=120}
===============================
Important HashMap methods
get()
: Retrieve value from the HashMap
put()
: Put value into the HashMap
isEmpty
: Check if HashMap is empty.
containsKey()
: Check if key present is HashMap
containsValue()
: Check if value exists in HashMap
size()
: Check size of the HashMap
clear()
: To remove all elements from Hashmap
clone()
: It creates shallow copy of HashMap.
Here is an example to cover these methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package org.arpit.java2blog.HashMap; import java.util.HashMap; public class HashMapMethodsMain { public static void main(String[] args) { HashMap<String, String> employeeDeptmap = new HashMap<>(); //check if map is empty boolean empty = employeeDeptmap.isEmpty(); System.out.println("is employeeDeptmap empty: "+empty); // Putting key-values pairs in HashMap employeeDeptmap.put("Arpit","Tech"); employeeDeptmap.put("John", "Sales"); employeeDeptmap.put("Martin", "HR"); employeeDeptmap.put("Vaibhav","Tech"); System.out.println(employeeDeptmap); //check size of map System.out.println("size of employeeDeptmap: "+employeeDeptmap.size()); // get value from HashMap System.out.println("Martin's department: "+employeeDeptmap.get("Martin")); // Robin's department will be null as we don't have key as "Robin" System.out.println("Robin's department: "+employeeDeptmap.get("Robin")); if(employeeDeptmap.containsKey("John")) { System.out.println("employeeDeptmap has John as key"); } if(employeeDeptmap.containsValue("Sales")) { System.out.println("employeeDeptmap has Sales as value"); } // Removing all entries from Map employeeDeptmap.clear(); System.out.println(employeeDeptmap); } } |
Output:
{Arpit=Tech, John=Sales, Martin=HR, Vaibhav=Tech}
size of employeeDeptmap: 4
Martin’s department: HR
Robin’s department: null
employeeDeptmap has John as key
employeeDeptmap has Sales as value
{}
Write declarative style code with HashMap
Java 8‘s Map interface introduced new methods such as compute(), computeIfPresent() and computeIfAbsent()
which help you write code using lambda expressions.
compute()
Let’s say you have a HashMap of team and no. of goal as below.
1 2 3 4 5 |
HashMap<String,Integer> teamGoalMap=new HashMap<>(); teamGoalMap.put("team1",1); teamGoalMap.put("team2",1); |
Now you want to add 1 goal to team1
and generally, you do it as follow.
1 2 3 |
teamGoalMap.put("team1",teamGoalMap.get("team1")+1); |
Instead, you can easily do it with compute as below.
1 2 3 |
teamGoalMap.compute("team1",(team,goal) ->goal+1); |
So whenever you want to apply mappings based on key, value pair then compute should be used.
computeIfPresent()
computeIfPresent recomputes the value if specified key is present and value is not null.
You might have written code like below before:
1 2 3 4 5 6 |
if(teamGoalMap.containsKey("team1")) { teamGoalMap.put("team1",teamGoalMap.get("team1")+1); } |
You can rewrite this with computeIfPresent
as below
1 2 3 |
teamGoalMap.computeIfPresent("team1",(team,goal) ->goal+1); |
If function returns null, then key will be removed from HashMap.
computeIfAbsent()
computeIfAbsent recomputes the value if specified key is not present and function does not return null.
You might have written code like below before:
1 2 3 4 5 6 |
if(!teamGoalMap.containsKey("team3")) { teamGoalMap.put("team3",0); } |
You can rewrite this with computeIfAbsent
as below
1 2 3 |
teamGoalMap.computeIfAbsent("team3",value -> 0); |
If key is already present in map, then nothing will change.
Let’s see another example to rewrite HashMap code in a declarative style.
Problem: You want to find the frequency of each character in String.
You might have written the program in a trivial way as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package org.arpit.java2blog.HashMap; import java.util.HashMap; public class FrequencyOfEachWord { public static void main(String[] args) { String str = "thisisjavablog"; HashMap<Character,Integer> hMap = new HashMap<>(); for(int i= 0 ; i< str.length() ; i++) { Character c=str.charAt(i); if(hMap.containsKey(c)) { int count = hMap.get(c); hMap.put(c,count+1); } else { hMap.put(c,1); } } System.out.println(hMap); } } |
Output:
Above program uses simple logic to count frequency of each character in String.
- Create a HashMap which will contain character to count mapping.
- Iterate over String character by character
- If Character is not present in map, then count should be 1
- If Character is already present in map, then increment its count by 1
Let’s rewrite this logic using computeIfPresent
and computeIfAbesent
methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package org.arpit.java2blog.HashMap; import java.util.HashMap; public class FrequencyOfEachWord { public static void main(String[] args) { String str = "thisisjavablog"; HashMap<Character,Integer> hMap = new HashMap<>(); for(int i= 0 ; i< str.length() ; i++) { Character c=str.charAt(i); hMap.computeIfPresent(c, (character,count)-> count+1); hMap.computeIfAbsent(c, (character)-> 1); } System.out.println(hMap); } } |
Output:
As you can see, logic looks quite readable in case of computeIfPresent
and computeIfAbesent
methods.
Get entrySet(), keySet() and values() from HashMap
entrySet()
entrySet()
: As HashMap stores key value pair in form of Entry
, we can retrieve entrySet() by calling map.entrySet()
keySet()
keySet()
: Provides a set of keys.
values()
values()
: Provides a collection of values.
Here is the example for the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package org.arpit.java2blog; import java.util.Collection; import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; public class HashMapEntrySetMain { public static void main(String[] args) { HashMap<Integer, String> studentIDNameMap = new HashMap<>(); // Putting key-values pairs in HashMap studentIDNameMap.put(101,"Andy"); studentIDNameMap.put(102, "Mary"); studentIDNameMap.put(103, "Sam"); studentIDNameMap.put(104,"Sandy"); // get entrySet Set<Entry<Integer, String>> entrySet = studentIDNameMap.entrySet(); System.out.println("EntrySet: "+entrySet); // get keySet Set<Integer> keySet = studentIDNameMap.keySet(); System.out.println("keySet: "+keySet); // get values Collection<String> values = studentIDNameMap.values(); System.out.println("values: "+values); } } |
Output:
Iterate over HashMap
There are many ways to iterate over HashMap
- Iterating over HashMap using
keyset()
- Iterating over HashMap using
keyset()
with foreach() and lambda expression[ java 8] - Iterating over HashMap using foreach()and lambda expression [java 8]
- Iterating over HashMap’s
entrySet()
usingiterator
- Iterating over HashMap’s
entrySet()
using foreach() and lambda expression [java 8] - Iterating over HashMap’s
entrySet()
using foreach loop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
package org.arpit.java2blog.HashMap; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class HashMapIterationMain { public static void main(String[] args) { HashMap<String, String> userCountryMap = new HashMap<>(); // Putting key-values pairs in HashMap userCountryMap.put("Anchit","India"); userCountryMap.put("Andy", "USA"); userCountryMap.put("Roy", "Germary"); userCountryMap.put("Mary","France"); System.out.println("========================================================="); System.out.println("Iterating over HashMap with foreach and lambda:"); userCountryMap.forEach((user,country) -> { System.out.println(user+" --> "+country); } ); System.out.println("========================================================="); System.out.println("Iterating over HashMap using keyset() with foreach loop:"); for(String user:userCountryMap.keySet()) { System.out.println(user+" --> "+userCountryMap.get(user)); } System.out.println("========================================================="); System.out.println("Iterating over HashMap's keyset() with foreach and lambda:"); userCountryMap.keySet().forEach((user) -> { System.out.println(user+" --> "+userCountryMap.get(user)); } ); System.out.println("========================================================="); System.out.println("Iterating over HashMap's entrySet with iterator"); Iterator<Entry<String, String>> iterator = userCountryMap.entrySet().iterator(); while(iterator.hasNext()) { Entry<String, String> next = iterator.next(); System.out.println(next.getKey()+" --> "+next.getValue()); } System.out.println("========================================================="); System.out.println("Iterating over HashMap's entrySet with foreach and lambda"); userCountryMap.entrySet().forEach((entry) -> { System.out.println(entry.getKey()+" --> "+entry.getValue()); } ); System.out.println("========================================================="); System.out.println("Iterating over HashMap's entrySet with foreach loop"); for(Map.Entry<String, String> entry:userCountryMap.entrySet()) { System.out.println(entry.getKey()+" --> "+entry.getValue()); } } } |
Iterating over HashMap with foreach and lambda:
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
=========================================================
Iterating over HashMap using keyset() with foreach loop:
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
=========================================================
Iterating over HashMap’s keyset() with foreach and lambda:
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
=========================================================
Iterating over HashMap’s entrySet with iterator
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
=========================================================
Iterating over HashMap’s entrySet with foreach and lambda
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
=========================================================
Iterating over HashMap’s entrySet with foreach loop
Anchit –> India
Andy –> USA
Roy –> Germary
Mary –> France
Storing Custom objects as Key
You can store custom objects as Key in HashMap but you should implement hashcode and equals method, otherwise it may not work as expected.
Country.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package org.arpit.java2blog; public class Country { String name; long population; public Country(String name, long population) { super(); this.name = name; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + (int) (population ^ (population >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Country other = (Country) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Country: "+name+" | population:"+population; } } |
HashMapMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package org.arpit.java2blog; import java.util.HashMap; public class HashMapMain { public static void main(String args[]) { Country india=new Country("India",10000); Country japan=new Country("Japan",3000); Country france=new Country("France",5000); Country russia=new Country("Russia",4000); // HashMap with Country name as key and capital as value // HashMap stores elements in key value pairs HashMap<Country,String> countryCapitalMap=new HashMap<>(); countryCapitalMap.put(india,"Delhi"); countryCapitalMap.put(japan,"Tokyo"); countryCapitalMap.put(france,"Paris"); countryCapitalMap.put(russia,"Moscow"); System.out.println("-----------------------------"); // Iterating HashMap Using keySet() and for each loop System.out.println("Iterating HashMap Using keySet() and for each loop"); for (Country countryKey:countryCapitalMap.keySet()) { System.out.println(countryKey +" and Capital:"+countryCapitalMap.get(countryKey)); } System.out.println("-----------------------------"); } } |
Iterating HashMap Using keySet() and for each loop
Country: Japan | population:3000 and Capital:Tokyo
Country: India | population:10000 and Capital:Delhi
Country: Russia | population:4000 and Capital:Moscow
Country: France | population:5000 and Capital:Paris
—————————–
Sort HashMap in java
By Keys
We can sort keys in HashMap by using TreeMap. We just need to pass a HashMap to the constructor of TreeMap.
By Values
We need to follow below steps to sort HashMap by values.
- Get
entrySet()
from HashMap - convert entrySet to
List
- Sort the list with the help of Comparator
- Iterate over list and put the Entry object in LinkedHashMap
Let’s write an example to sort HashMap by keys and values. We will create a class named Vehicle and will use it as Key in HashMap and value will be the owner of the Vehicle.
Create a class named Vehicle.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package org.arpit.java2blog; public class Vehicle implements Comparable<Vehicle>{ String name; long maxSpeed; public Vehicle(String name, long maxSpeed) { super(); this.name = name; this.maxSpeed = maxSpeed; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(long maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Vehicle name: "+name+"|Max speed: "+maxSpeed; } @Override public int compareTo(Vehicle v) { return this.getName().compareTo(v.getName()); } } |
Please note that we have implemented comparable interface here which compares two vehicle by its name. This Comparable
will be used to sort it by Keys while constructing TreeMap.
Create a class named HashMapSortMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
package org.arpit.java2blog; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; public class HashMapSortMain { public static void main(String[] args) { Vehicle v1=new Vehicle("Car", 150); Vehicle v2=new Vehicle("Truck", 130); Vehicle v3=new Vehicle("Bike", 150); Vehicle v4=new Vehicle("Jeep", 180); // HashMap stores elements in key value pairs HashMap<Vehicle,String> vehicleOwnerMap=new HashMap<>(); vehicleOwnerMap.put(v1,"John"); vehicleOwnerMap.put(v2,"Chris"); vehicleOwnerMap.put(v3,"Mary"); vehicleOwnerMap.put(v4,"Harry"); // Sort by keys // As Vehicle class implements Comparable which defines sorting by vehicle name TreeMap<Vehicle,String> treeMap=new TreeMap<Vehicle,String>(vehicleOwnerMap); System.out.println("Sorted TreeMap by vehicle name: "+treeMap); // Sort by values Set<Entry<Vehicle, String>> entrySet = vehicleOwnerMap.entrySet(); List<Entry<Vehicle, String>> vehicleEntryList=new ArrayList<>(entrySet); Collections.sort(vehicleEntryList,(e1,e2) -> e1.getValue().compareTo(e2.getValue())); LinkedHashMap<Vehicle, String> lmp=new LinkedHashMap<Vehicle, String>(); vehicleEntryList.forEach((entry)-> { lmp.put(entry.getKey(), entry.getValue()); }); System.out.println("Sorted Map by owner name: "+lmp); } } |
Output:
If you don’t understand the syntax of lambda expression which we have used above to sort List of Entry objects,then you need to go through Lambda Expression in Java 8.
is HashMap thread-safe?
HashMap is not thread-safe by default and it can give non-deterministic results in case of a multithreaded environment.
Let’s demonstrate this with the help of an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
package org.arpit.java2blog; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Counter { public static void main(String[] args) throws InterruptedException { Map<String, Integer> counterMap=new HashMap<>(); counterMap.put("counter1",0); counterMap.put("counter2",100); ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); Runnable counterTask = () -> { incrementTime(counterMap,"counter1"); incrementTime(counterMap,"counter2"); }; for (int i = 1; i <= 100; i++) { newFixedThreadPool.submit(counterTask); } newFixedThreadPool.shutdown(); newFixedThreadPool.awaitTermination(30, TimeUnit.SECONDS); System.out.println("Time for Counter1: "+counterMap.get("counter1")); System.out.println("Time for Counter2: "+counterMap.get("counter2")); } public static void incrementTime(Map<String,Integer> counterMap,String counter) { Integer count = counterMap.get(counter) count++; counterMap.put(counter,count); } } |
I have put two entries in map with key as counter1 and counter2 and value as time 0 and 100 respectively.We have created a task which increment time for both counter by 1 and we are using ExecuterService to submit it 100 times.
Let’s run the program and check output:
Time for Counter2: 195
but our expected output should be
Time for Counter2: 200
because we have submitted task 100 times and in each task execution, it calls
incrementTime()Â and increases the time by 1.
Let’s run the program again.
Time for Counter2: 197
It is different from the last execution and this is due to thread-safety issues in HashMap.
We can solve this thread safety issue in two ways:
- Collections.synchronizedMap
- ConcurrentHashmap
Collections.synchronizedMap
We can use Collections.synchronizedMap()
to make all operations of HashMap thread safe and make
incrementTime()Â method synchronized to solve above issue.
incrementTime()Â should be also synchronized otherwise there will be atomicity issues.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package org.arpit.java2blog.HashMap; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Counter { public static void main(String[] args) throws InterruptedException { Map<String, Integer> counterMap=Collections.synchronizedMap(new HashMap<>()); counterMap.put("counter1",0); counterMap.put("counter2",100); ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); Runnable counterTask = () -> { incrementTime(counterMap,"counter1"); incrementTime(counterMap,"counter2"); }; for (int i = 1; i <= 100; i++) { newFixedThreadPool.submit(counterTask); } newFixedThreadPool.shutdown(); newFixedThreadPool.awaitTermination(30, TimeUnit.SECONDS); System.out.println("Time for Counter1: "+counterMap.get("counter1")); System.out.println("Time for Counter2: "+counterMap.get("counter2")); } public static synchronized void incrementTime(Map<String,Integer> counterMap,String counter) { Integer count = counterMap.get(counter); count++; counterMap.put(counter,count); } } |
Output:
Time for Counter2: 200
As you can see, we are getting correct output after using Collections.synchronizedMap()
and making incrementTime
synchronized.
ConcurrentHashMap
The disadvantage of using Collections.synchronizedMap() is that it locks whole hashmap object and which may cause performance issue but ConcurrentHashMap only locks part of the map and performs quite well in a multithreaded environment.
How HashMap works internally
This topic deserves separate post, so I have written complete tutorial on How HashMap works in java.
Java 8 HashMap update
To understand this change, you need to understand How HashMap works internally.Java 8 has introduced good performance improvement in case of too many hash collisions.
Before Java 7
If two objects have the same hashcode and are not equal, then both will be stored at the same bucket
with the help of the singly linked list. In case, there are too many hash collisions, then the performance of get()
and put()
may suffer.
In the worst case, if all keys have same hashcode then get()
operation in HashMap may take O(n) time.
Java 8 Update
In Java 8, HashMap changes the linked list to a binary tree in case number of elements reaches a certain threshold. With the help of this change, get() operation in HashMap may take O(log(n)) time in the worst case.
Java HashMap tutorial
- HashMap in java
- How HashMap works in java
- hash and indexfor method in HashMap
- hashcode and equals method in java
- How to sort HashMap by keys and values
- Difference between HashMap and HashSet
- Difference between HashMap and Hashtable
- How to iterate over HashMap
Conclusion
You have learned about basics of HashMap, how to create a HashMap and add key-value pairs to it, important HashMap methods, how to write declarative style code with HashMap, how to iterate over HashMap and thread safety issues with HashMap and how to synchronized a HashMap.