Adding a value to a list to an already existing key in Map

11,289

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);
    }
}
Share:
11,289
Joe
Author by

Joe

A lover of design and art.

Updated on June 07, 2022

Comments

  • Joe
    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
    Boris the Spider about 8 years
    Or even myMap.computeIfAbsent("Tests", k -> new ArrayList<>()), for the next question of "why did I get a NullPointerException with a different key".
  • dabadaba
    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
    Boris the Spider about 8 years
    @dabadaba, yes - as it has a lambda. What would the one for put do exactly?
  • Jorn Vernee
    Jorn Vernee about 8 years
    @BoristheSpider Are you sure getOrDefault can take a supplier? HashMap Javadoc. There are no overloads.
  • Joe
    Joe about 8 years
    Thank you so much for your help everyone! I will make sure to follow this information.
  • Jorn Vernee
    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
    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 if containsKey(k) and if the value is an initalized list (not null). So I am talking about a method that would a) create a new list, add the element to it and then set is as ks value or b) simply add the element to the existing value list
  • Boris the Spider
    Boris the Spider about 8 years
    @dabadaba isn't that exactly what the above does?
  • dabadaba
    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
    Boris the Spider about 8 years
    @dabadaba you want to get a value from a Map, and if there is no value present compute a new value a put it into the Map. The method then either returns the get or the new value. Finally you do whatever you want with that value - in your example it's a List so you add. I'm not convinced you've read the documentation.
  • dabadaba
    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
    dabadaba about 8 years
    But 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
    Rogue about 8 years
    It 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
    Jan over 6 years
    I like the one-liner (second to last line).