Java collection classes allow a developer to keep track of contained items in one of two ways, either by an indexed count or a key. This creates an obvious limitation where multiple values can’t be associated with the same key or index. In turn, this can be problematic when a developer generates XML or JSON that employs such a syntax.
Fortunately, there are a few strategies to overcome this problem. Here are few examples of how to make multiple values per key in a Java map component possible.
Java’s multiple values per key problem
Here’s a look at the multiple value per key Java problem in code:
HashMap<String, String> haloCars = new HashMap<String, String>(); haloCars.put("ford", "GT"); haloCars.put("dodge", "Viper"); //next line wipes out the value "GT" in the "ford" key haloCars.put("ford", "Mustang Mach-E"); System.out.println(haloCars.get("ford")); //prints out "Mustang Mach-E"
The key ‘ford’ is used twice and the second usage overwrites the first.
A Java standard library solution
The easiest approach to solve this problem is through the standard Java libraries. Embed a collection class, such as an ‘ArrayList’ within the Map as follows:
|Website Performance Tips and Tricks|
Is website performance a problem? It doesn’t have to be. Here’s how to fix it:
With these tips and tricks on hand, application performance will not be a problem.
Map<String, ArrayList<String>> multiValueMap = new HashMap<String, ArrayList<String>>(); multiValueMap.put("ford", new ArrayList<String>()); multiValueMap.get("ford").add("GT"); multiValueMap.get("ford").add("Mustang Mach-E"); multiValueMap.get("ford").add("Pantera");
In this case, when a developer accesses the key ‘ford’, all three of the associated values will be returned.
When a developer adds multiple values to a single key in a Java map through the standard APIs, it won’t introduce any new dependencies into the code and it will work with any JDK version. However, one drawback to this approach is that the code tends to look messy.
A cleaner approach is to introduce a third-party Java library such as Google Guava or Apache Commons, both of which provide a Multimap class to address the issue.
Multiple values per key with Apache Commons
In Apache Commons collection classes in a Maven project, add the following entry to the POM:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency>
With the POM updated, the code is relatively straight forward:
MultiMap multiMap = new MultiValueMap(); multiMap.put("ford", "Mustang Mach-E"); multiMap.put("ford", "GT"); multiMap.put("ford", "Pantera"); System.out.println(multiMap.get("ford"));
Multiple values per key with Google Guava
With Google Guava on a Maven project, add the following entry to the POM:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency>
The Guava entry looks very similar to the Apache Commons code, but the biggest difference between the two is the casing on the name Multimap.
Multimap<String, String> map = ArrayListMultimap.create(); map.put("ford", "Mustang Mach-E"); map.put("ford", "Pantera"); Collection<String> values = map.get("ford"); System.out.println(values);
How to add multiple values per key to a Java HashMap
It seems like an oversight for the standard Java API not to have a collection class that allows a key to have multiple values. If this is an application requirement, the three best ways to solve the ‘multiple values per key in a map in Java’ problem are:
- Stick with the standard APIs and add a collection class like a ‘Vector’ or ‘ArrayList’ to your map or set.
- Use the MultiMap and MultiValueMap classes from the Apache Commons library.
- Use the third-party Google Guava library and the included Multimap and ArrayListMultimap classes.