Table of Contents
This article discusses the HashMap
in Java and how to add multiple values for Single Key In HashMap in Java.
HashMap
The HashMap in Java is an instrument that allows efficient access, insertion, deletion, and updating using the indexing concept by storing data in the form of key and value pairs.
It was introduced in the Java 1.2 version and hence has been a part of the Java Collection library.
It is included in java.util package
. Java 5 denotes HashMaps
as HashMap
where K
stands for the Key and V
stands for the Value.
Can HashMap Store Multiple Values Automatically
HashMap
shares similarities with HashTable
, apart from the fact that it is asynchronous. It implies that HashMap
can store null keys which HashTable
cannot.
HashMap
allows storage for any number of Null Values, but there has to be only one Null Key in the whole Map.
Another important property of HashMap
is that if it encounters a different value for an already existing key, it overwrites the value for the same key.
This is what can sometimes be not wanted for a programming use case. And thus in this article, we will discuss a workaround for storing multiple values to the same key in HashMap
in Java.
Ways to Add Multiple Values for Single Key In HashMap in Java
Using the Standard Library
If you are required to add different values under the same key, one of the methods could be to use a Java collection class such as an ArrayList, List
, etc.
There are many such collections classes in Java that you can embed inside the HashMap
, this would enable the whole collection to come under the same key in the HashMap
.
The following sample code uses the ArrayList
from java.util
library. It is used to store the different values which later become a part of the HashMap
.
Let us look at the following Java code for a better understanding of how it works.
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 |
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class Sample { public static void main(String[] args) { Map<Integer,ArrayList<String>> Hmap=new HashMap<Integer,ArrayList<String>>(); Hmap.put(4, new ArrayList<String>()); Hmap.put(5, new ArrayList<String>()); Hmap.get(4).add("1+3"); Hmap.get(4).add("2+2"); Hmap.get(4).add("3+1"); Hmap.get(5).add("1+4"); Hmap.get(5).add("2+3"); Hmap.get(5).add("3+2"); Hmap.get(5).add("4+1"); for(Map.Entry<Integer,ArrayList<String>> entry: Hmap.entrySet()) { Integer key=entry.getKey(); ArrayList<String> values=entry.getValue(); System.out.println(key+"="+values); } } } |
Output :
In the above code, different combinations that make up a number are put under the same key in the HashMap
.
The HashMap
uses the Integer class and the ArrayList
of Strings. The Strings are different combinations, for example, the string “1+3” results in 4, which is the key value for that string.
Further reading:
Using Apache Commons Library
Apache Commons library extends the Java API, it is a complete package with a very useful set of utility classes.
You need to add below dependency to get Apache commons jar.
1 2 3 4 5 6 7 |
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency> |
It has implementations on many ordered data structures and manipulations of basic data structures.
You can use the MultiMap
and MultiValueMap
available in the Apache Commons collections library to store multiple values in the same key.
The following code illustrates 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 |
import java.util.Set; import org.apache.commons.collections4.MultiMap; import org.apache.commons.collections4.map.MultiValueMap; public class Sample { public static void main(String[] args) { MultiMap<Integer, String> Hmap=new MultiValueMap<Integer, String>(); Hmap.put(4,"1+3"); Hmap.put(4,"2+2"); Hmap.put(4,"3+1"); Hmap.put(5,"1+4"); Hmap.put(5,"2+3"); Hmap.put(5,"3+2"); Hmap.put(5,"4+1"); Set<Integer> keys=Hmap.keySet(); for(Integer i : keys) { System.out.println(i+"="+Hmap.get(i)); } } } |
Output:
The above code implements the same example of storing combinations of numbers is with the output of the combinations stored as keys in the Hash Map.
However, the implementation is using the Apache Commons library that you can add as an external jar file or as dependency in the pom file of maven project.
Using Google Guava Library
Google guava is another similar library built by google, it was primarily developed for java projects within google, but it was hosted as an open source library.
You can use the Google Guava Library on any maven project similar to the Apache Commons library.
Here is the dependency which you need to add for guava in pom.xml
.
1 2 3 4 5 6 7 |
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency> |
This example uses the ArrayListMultiMap
from the google guava library.
Similar to the Apache Commons library you can add this library as dependency in the pom file of maven project or as an external jar file library.
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 |
import java.util.Set; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class Sample { public static void main(String[] args) { ArrayListMultimap<Integer, String> Hmap =new ArrayListMultimap<Integer,String>(); Hmap.put(4,"1+3"); Hmap.put(4,"2+2"); Hmap.put(4,"3+1"); Hmap.put(5,"1+4"); Hmap.put(5,"2+3"); Hmap.put(5,"3+2"); Hmap.put(5,"4+1"); Set<Integer> keys=Hmap.keySet(); for(Integer i : keys) { System.out.println(i+"="+Hmap.get(i)); } } } |
Output :
This code imports the ArrayListMultimap
from google guava and uses for making the multi map which again stores the combinations in the same output key in the hash map.
Using TreeSet as Values
TreeSet
is a very useful data set as it implements the navigable set which is derived from the sorted set which is again derived from the set class of the java library.
It comes handy when there is a requirement to store a huge amount of data but access to it has to be fast.
Note that you cannot insert null value into TreeSet
as it cannot be compared to any other already existing data in the TreeSet
.
We will continue with the above example of implementing storage of combinations of numbers in the same key of a Hash Map.
The following example code explains how TreeSet
can be embedded into the HashMap
in 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 |
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Set; import java.util.TreeSet; public class Sample { public static void main(String[] args) { HashMap<Integer,TreeSet<String>> Hmap=new HashMap<>(); List<String> l4=new ArrayList<String>(); l4.add("3+1"); l4.add("2+2"); l4.add("1+3"); List<String> l5=new ArrayList<String>(); l5.add("4+1"); l5.add("3+2"); l5.add("2+3"); l5.add("1+4"); Hmap.put(4, new TreeSet<String>(l4)); Hmap.put(5, new TreeSet<String>(l5)); Set<Integer> keys = Hmap.keySet(); for (Integer i : keys) { System.out.println(i+"=" + Hmap.get(i)); } } } |
Output :
As you can observe, the above code prints the output in the sorted order when implemented with the TreeSet
embedded into the HashMap
.
Access to HashMap
values may be quicker but as you can see it may require extra usage of memory because lists are separately initialized.
Using a Wrapper Class
Wrapper Class in general in Java refers to a class which converts a primitive data type into objects of a class or from objects of a class to a primitive data type.
We have used the Integer Class in previous example codes which is an example of a wrapper class which wraps the primitive data type ‘int’.
We can also use Wrapper Class for an array or List of Objects.
To understand how wrapper class can help in getting multiple values under the same key in HashMap
, let us look at the following code.
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 |
import java.util.HashMap; import java.util.Set; class Wrapped { private String[] combination; public Wrapped(String[] combinations) { this.combination=combinations; } public String[] getcombo() { return this.combination; } } public class Sample { public static void main(String[] args) { HashMap<Integer,Wrapped> Hmap=new HashMap<>(); String[] l4= {"3+1","2+2","1+3"}; String[] l5= {"4+1","3+2","2+3","1+4"}; Hmap.put(4, new Wrapped(l4)); Hmap.put(5, new Wrapped(l5)); Set<Integer> keys = Hmap.keySet(); for (Integer i : keys) { String[] temp=Hmap.get(i).getcombo(); System.out.print(i+"="); for(int j=0;j<temp.length;j++) { System.out.print("["+temp[j]+"] "); } System.out.println(); } } } |
Output:
In the above sample code, Wrapper Class wraps an array of Strings which is a private member of the class.
The HashMap
declared in the main class thus only has to implement an Integer for the key and for values, an object of the “Wrapped” class, allowing us to store multiple values under the same key.
Using Java Tuples
Tuples in Java provides another solution for combining elements.
A tuple is considered to be an ordered data structure that can contain different data types, these might not be connected to one another but as a whole has a significant meaning.
A noteworthy point about Tuples is that they are immutable, i.e once created they cannot be changed.
The Tuples Library in Java consists of many useful classes such as the Unit, Pairs, Triplets, Quartets, etc.
You need to add below dependency to get javatuples jar.
1 2 3 4 5 6 7 8 |
<!-- https://mvnrepository.com/artifact/org.javatuples/javatuples --> <dependency> <groupId>org.javatuples</groupId> <artifactId>javatuples</artifactId> <version>1.2</version> </dependency> |
To understand how it can be used for storing multiple values under the same key in Hash Map in Java, let us look at the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.util.HashMap; import java.util.Set; import org.javatuples.Triplet; public class Sample { public static void main(String[] args) { HashMap<Integer,Triplet<String,String,String>> Hmap=new HashMap<>(); Hmap.put(4, new Triplet<String,String,String>("1+3","2+2","3+1")); Set<Integer> keys = Hmap.keySet(); for (Integer i : keys) { System.out.print(i+"="+Hmap.get(i)); } } } |
Output :
This sample code uses the Triplet Class of Java from the JavaTuples
Library.
This code creates the Hash Map of Integer and Triplet. While populating the hash map the code creates an object of the Triplet class as shown in the code.
Using compute() Function in JDK 8
If you are using a JDK version 8 or newer, you can make use of the compute()
function as well.
The map.compute() function is a remapping function that allows the manipulation of the values inside the Hash Maps of Java.
Another point to note while using compute functions is to make sure that it does not alter the existing map.
Thus, this compute function can be used to manipulate the values such that multiple values are added to the same key.
The compute()
function is generally used for updating values based on specific conditions. However, we can make simple changes into its embedding so as to make it useful in our use case.
To understand how this concept works, let us look at the following piece of code.
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 |
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class Sample { private static <KEY, VALUE> void put(Map<KEY, List<VALUE>> map, KEY key, VALUE value) { map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value); } public static void main(String[] args) { Map<Integer,List<String>> Hmap=new HashMap<>(); put(Hmap,4,"1+3"); put(Hmap,4,"2+2"); put(Hmap,4,"3+1"); put(Hmap,5,"1+4"); put(Hmap,5,"2+3"); put(Hmap,5,"3+2"); put(Hmap,5,"4+1"); Set<Integer> keys = Hmap.keySet(); for (Integer i : keys) { System.out.println(i+"="+Hmap.get(i)); } } } |
Output:
On closer observation, you can see that the code explicitly modifies the put() function and uses it for insertion into the Hash Map.
The code declares the put()
function as private static and it takes the three parameters as Map, Key, and Value.
Inside the function, the code uses the map.compute()
function that creates an ArrayList
if not already existing and if it does, adds the new value into it.
Conclusion
These are the different ways that you can use when there is a need to add multiple values into the same key of a Hash Map in Java.
The easiest way is to use the standard library data structures such as the ArrayList
, etc.
However, if you are working on a maven project it could be easier to use MultiMap
from external libraries such as google guava and Apache Commons as discussed in the article.
This article also discussed other workarounds like Java Tuples, Wrapper Class, the compute() function, and TreeSet
as Values, for the problem, which may not be easy to implement but can be efficient depending upon the use case.
This is all about how to add multiple values for Single Key in HashMap in Java
Hope you have learned something new and enjoyed reading the article. Stay tuned for more such articles. Happy learning!