Adding a value to a list to an already existing key in Map
Solution 1
Simply get the list from the map and then add the element to the list:
ArrayList list = myMap.get("Tests");
list.add("Test4");
There are some other things that can be remarked about your code. First of all, don't use the raw type ArrayList
. Use generics:
HashMap<String, ArrayList<String>> myMap = new HashMap<String, ArrayList<String>>();
ArrayList<String> myList = new ArrayList<String>();
myList.add("Test 1");
myList.add("Test 2");
myList.add("Test 3");
myMap.put("Tests", myList);
Second, program to interfaces, not implementations. In other words, program using interfaces Map
and List
rather than the implementations HashMap
and ArrayList
. This is a well-known OO programming principle, which makes it for example easier to switch to a different implementation, if necessary.
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
List<String> myList = new ArrayList<String>();
myList.add("Test 1");
myList.add("Test 2");
myList.add("Test 3");
myMap.put("Tests", myList);
Finally, a syntax tip: if you're using Java 7 or newer you can use <>
and you don't have to repeat the type arguments:
Map<String, List<String>> myMap = new HashMap<>();
List<String> myList = new ArrayList<>();
myList.add("Test 1");
myList.add("Test 2");
myList.add("Test 3");
myMap.put("Tests", myList);
myMap.get("Tests").add("Test 4");
Solution 2
I'd recommend using Map#computeIfAbsent
, to always ensure retrieving a List
from the map:
private final Map<String, List<String>> example = new HashMap<>();
private List<String> getList(String key) {
return this.example.computeIfAbsent(key, k -> new ArrayList<>());
}
//elsewheres
getList("test").add("foobar");
getList("test").forEach(System.out::println); // "foobar"
This means that if the map doesn't contain an entry for the key
, it will use the provided lambda to generate a new value for the key and return that.
Solution 3
import java.util.*;
class M {
public static void main( String ... args ) {
List<String> l = new ArrayList<>();
l.add("Test 1");
l.add("Test 2");
l.add("Test 3");
Map<String,List<String>> m = new HashMap<>();
m.put("Tests", l );
// some time later that day ...
m.computeIfAbsent("Tests", k -> new ArrayList<>()).add("Test 4");
System.out.println(m);
}
}
Comments
-
Joe almost 2 years
Evening!
I have the following Map:
HashMap<String, ArrayList> myMap = new HashMap<String, ArrayList>();
I then added the following data to it:
ArrayList myList = new ArrayList(); myList.add("Test 1"); myList.add("Test 2"); myList.add("Test 3"); myMap.put("Tests", myList);
This left me with the following data:
Key: Tests
Values: Test 1, Test 2, Test 3
My question is, how do I then add new values on to my already existing key? So for example, how could I add the value "Test 4" onto my key "Tests".
Thanks.
-
Boris the Spider about 8 yearsOr even
myMap.computeIfAbsent("Tests", k -> new ArrayList<>())
, for the next question of "why did I get aNullPointerException
with a different key". -
dabadaba about 8 years@BoristheSpider wow I didn't know this one. Was it introduced in Java 8? Also is there a similar one for
put
? -
Boris the Spider about 8 years@dabadaba, yes - as it has a lambda. What would the one for
put
do exactly? -
Jorn Vernee about 8 years@BoristheSpider Are you sure
getOrDefault
can take a supplier? HashMap Javadoc. There are no overloads. -
Joe about 8 yearsThank you so much for your help everyone! I will make sure to follow this information.
-
Jorn Vernee about 8 years@BoristheSpider That would be a nice feature though ;) I was wondering why I never heard about it (in my mind maybe some 3rd party libray or something).
-
dabadaba about 8 years@BoristheSpider imagine you have a
Map<K, List<V>>
. If you want to add a new value to a existing or not key you need to check ifcontainsKey(k)
and if the value is an initalized list (notnull
). So I am talking about a method that would a) create a new list, add the element to it and then set is ask
s value or b) simply add the element to the existing value list -
Boris the Spider about 8 years@dabadaba isn't that exactly what the above does?
-
dabadaba about 8 years@BoristheSpider no... what you said is a "getter", I am talking about a "setter". edit: Wait you just changed the method, I was talking about
getOrDefault
... -
Boris the Spider about 8 years@dabadaba you want to
get
a value from aMap
, and if there is no value presentcompute
a new value aput
it into theMap
. The method then either returns theget
or the new value. Finally you do whatever you want with that value - in your example it's aList
so youadd
. I'm not convinced you've read the documentation. -
dabadaba about 8 years@BoristheSpider and I am convinced you edited your comment without letting me know so what I said above referred to the content of your comments before your edit ;)
-
dabadaba about 8 yearsBut that's putting the value in the map right? I am not sure I like the idea of putting data in a collection if we're using a getter method.
-
Rogue about 8 yearsIt places the value if it is absent, the idea is you're defaulting. If the resource isn't available for you, it will make it and provide the new resource. Perfectly valid.
-
Jan over 6 yearsI like the one-liner (second to last line).