HashMap in java

HashMap is hash table based implementation of Map interface. It stores entry in key-value pairs. It maps keys to values. It is one of the most used Collection.

Java HashMap

HashMap

  1. HashMap implements Map an interface that maps a key to value.
  2. It is not synchronized and is not thread-safe.
  3. Duplicate keys are not allowed
  4. One null key and multiple null values are allowed
  5. It is the unordered collection and does not give a guarantee for any specific order of elements.

HashMap

Did you notice HashMap implements Map interface even if AbstractMap already implements it?
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:

When you run above program, you will get below output

{1=Arpit, 2=John, 3=Martin, 4=Vaibhav}

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.

  1. remove(Object key): It removes key from HashMap
  2. remove(Object key,Object value): It removes key if value is same as passed parameter value.
Output:

{Car=220, Activa=140, Truck=160, Bike=120}
===============================
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.

Output:

is employeeDeptmap empty: true
{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.

Now you want to add 1 goal to team1 and generally, you do it as follow.

Instead, you can easily do it with compute as below.

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:

You can rewrite this with computeIfPresent as below

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:

You can rewrite this with computeIfAbsent as below

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.

Output:

{a=2, b=1, s=2, t=1, v=1, g=1, h=1, i=2, j=1, l=1, o=1}

Above program uses simple logic to count frequency of each character in String.

  1. Create a HashMap which will contain character to count mapping.
  2. Iterate over String character by character
  3. If Character is not present in map, then count should be 1
  4. If Character is already present in map, then increment its count by 1

Let’s rewrite this logic using computeIfPresent and computeIfAbesent methods.

Output:

{a=2, b=1, s=2, t=1, v=1, g=1, h=1, i=2, j=1, l=1, o=1}

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.

Output:

EntrySet: [101=Andy, 102=Mary, 103=Sam, 104=Sandy] keySet: [101, 102, 103, 104] values: [Andy, Mary, Sam, Sandy]

Iterate over HashMap

There are many ways to iterate over HashMap

  1. Iterating over HashMap using keyset()
  2. Iterating over HashMap using keyset() with foreach() and lambda expression[ java 8]
  3. Iterating over HashMap using foreach()and lambda expression [java 8]
  4. Iterating over HashMap’s entrySet() using iterator
  5. Iterating over HashMap’s entrySet() using foreach() and lambda expression [java 8]
  6. Iterating over HashMap’s entrySet() using foreach loop
Output:

=========================================================
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.

Create a class called Country.java
Create another class HashMapMain.java
When you run above program, you will get below output

—————————–
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.

  1. Get entrySet() from HashMap
  2. convert entrySet to List
  3. Sort the list with the help of Comparator
  4. 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

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

Output:

Sorted TreeMap by vehicle name: {Vehicle name: Bike|Max speed: 150=Mary, Vehicle name: Car|Max speed: 150=John, Vehicle name: Jeep|Max speed: 180=Harry, Vehicle name: Truck|Max speed: 130=Chris}Sorted Map by owner name: {Vehicle name: Truck|Max speed: 130=Chris, Vehicle name: Jeep|Max speed: 180=Harry, Vehicle name: Car|Max speed: 150=John, Vehicle name: Bike|Max speed: 150=Mary}

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:

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 Counter1: 95
Time for Counter2: 195

but our expected output should be

Time for Counter1: 100
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 Counter1: 98
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:

  1. Collections.synchronizedMap
  2. 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.

Output:

Time for Counter1: 100
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

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.

That’s all about HashMap in java.

Was this post helpful?


import_contacts

You may also like:

Related Posts

  • 20 September

    Return ArrayList in Java

    Table of ContentsReturn ArrayList in Java From a Static MethodReturn ArrayList in Java From a Non-static MethodConclusion This article discusses cases of returning an ArrayList in Java from a method. An ArrayList in Java is a collection of elements of the same data type under a single variable name. In different cases, you can return […]

  • 17 September

    Create List with One Element in Java

    Table of ContentsUsing Collections.singletonList()Using Array.asList() method [ Immuatable list]Using new ArrayList with Array.asList() method [ Mutable list] In this post, we will see how to create List with One Element in java.. Using Collections.singletonList() This is best way to create List with single element if you need an immutable List. [crayon-632fb59a92a34647030860/] Output [crayon-632fb59a92a3b012323473/] If you […]

  • 17 May

    How to Add Multiple Values for Single Key In HashMap in Java

    Table of ContentsHashMapCan HashMap Store Multiple Values AutomaticallyWays to Add Multiple Values for Single Key In HashMap in JavaUsing the Standard LibraryUsing Apache Commons LibraryUsing Google Guava LibraryUsing TreeSet as ValuesUsing a Wrapper ClassUsing Java TuplesUsing compute() Function in JDK 8Conclusion This article discusses the HashMap in Java and how to add multiple values for […]

  • java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
    22 February

    [Fixed] java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList

    Table of ContentsReason for java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayListFixes for java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayListUse ArrayList’s constructorAssign Arrays.asList() to List reference rather than ArrayList In this post, we will see how to fix java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList. ClassCastException is runtime exception which indicate that code has tried to […]

  • Java ArrayList of objects
    25 January

    Create ArrayList of Objects in Java

    Table of ContentsUsing the add() method to create ArrayList of objects in javaUsing parameterized constructor to create ArrayList of objects in javaUsing addAll() method to create ArrayList of objects in javaConclusion In this tutorial, we will learn how to create ArrayList of objects in Java. We will create a Book class with different properties and […]

  • 10 September

    How to remove element from Arraylist in java while iterating

    Table of ContentsIntroductionUsing Collection’s removeIf() methodUsing ListIterator classUsing removeAll() methodUsing Java 8 Stream to filter List itemsConclusion Introduction In this tutorial, you will learn how to remove element from Arraylist in java while iterating using different implementations provided by Java. It is necessary to understand the right way to remove items from a List because […]

Leave a Reply

Your email address will not be published.

Subscribe to our newletter

Get quality tutorials to your inbox. Subscribe now.