32

How to add element into ArrayList in HashMap?

    HashMap<String, ArrayList<Item>> Items = new HashMap<String, ArrayList<Item>>();

4 Answers 4

101

I know, this is an old question. But just for the sake of completeness, the lambda version.

Map<String, List<Item>> items = new HashMap<>();
items.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
Sign up to request clarification or add additional context in comments.

7 Comments

This works great. because computeIfAbsent () is intended to implement a multi-value map, Map<K, Collection<V>>, supporting multiple values per key
Best solution ever.
Somebody!! hand this guy a medal.
Nice job, this is fairly clean and should be accepted.
This answer resolved my issue. But I am curious how. I had a logic where I was checking for the value based on the key explicitly and then doing the insertion. SInce I am using spring webflux, ,multiple threads were accessing this map and giving inconsistent results. I tried using synchronised map and concurrentHashMap but both failed. Finally above computeIfAbsent worked and I have no clue why.Even the computeIfAbsent docs dont mention anything about concurrency write success guarantee.I have tested my new code N number of times and it works. Just that I am worried it might break in Prod
|
46
HashMap<String, ArrayList<Item>> items = new HashMap<String, ArrayList<Item>>();

public synchronized void addToList(String mapKey, Item myItem) {
    List<Item> itemsList = items.get(mapKey);

    // if list does not exist create it
    if(itemsList == null) {
         itemsList = new ArrayList<Item>();
         itemsList.add(myItem);
         items.put(mapKey, itemsList);
    } else {
        // add if item is not already in list
        if(!itemsList.contains(myItem)) itemsList.add(myItem);
    }
}

3 Comments

As noted in my answer, this is extremely un-thread-safe, but, if you are sure that that is not an issue it will work fine.
I assumed that datastructures are what's asked, but yeah for the sake of multi-threading let's add a synchronized.
There is a handy merge function on Map interface docs.oracle.com/javase/8/docs/api/java/util/…
9

First you have to add an ArrayList to the Map

ArrayList<Item> al = new ArrayList<Item>();

Items.add("theKey", al); 

then you can add an item to the ArrayLIst that is inside the Map like this:

Items.get("theKey").add(item);  // item is an object of type Item

1 Comment

Won't the method to add ArrayList to Map be 'put' instead of 'add' ?
7

Typical code is to create an explicit method to add to the list, and create the ArrayList on the fly when adding. Note the synchronization so the list only gets created once!

@Override
public synchronized boolean addToList(String key, Item item) {
   Collection<Item> list = theMap.get(key);
   if (list == null)  {
      list = new ArrayList<Item>();  // or, if you prefer, some other List, a Set, etc...
      theMap.put(key, list );
   }

   return list.add(item);
}

4 Comments

Is the synchronized flag actually helpful here? ArrayList and most standard collections aren't thread-safe, so ensuring this block is synchronized isn't that useful, right?
It ensures that the ArrayList is only created once. And, if this is the only place where you add to the List, that will be protected. However, in complex cases, if you really want thread-safety, use something other than ArrayList on the item = new ... line, such as CopyOnWriteArrayList etc...
I think there is an error here. Everywhere it says "item" in lines 4, 5 and 6 should probably say "list"
Wow - an error that big lasted for over a year. Nice catch Mike! Code has been corrected.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.