1

I have a HashMap

myMap = new HashMap<String, ArrayList<String> >();

I am writing a code where I want to add items in ArrayList for the key if it exists in the map,

myMap.get(key).add(element);

or else create a new ArrayList, add an item to the list, and add this list to the map.

ArrayList<String> tmpArrList = new ArrayList<>();
tmpArrList.add(element);
myMap.put(key, tmpArrayList);

Writing three lines for adding single element, do not look good to me, how can I write it in single line using Java 5.. ?

3 Answers 3

2

If you are using Java 8, computeIfAbsent is what you need :

myMap.computeIfAbsent(key, ArrayList::new).add(element);

This will generate a new ArrayList and put it in the Map if the requested key is not already present in the Map.

Sign up to request clarification or add additional context in comments.

2 Comments

Great !, but unfortunately, I have to write something which supports Java 1.5 and above
@SimpleGuy I don't think there is a 1-liner solution prior to Java 8 (unless you use some external libraries).
1

How can I write it in single line.. ? (from question)
I have to write something which supports Java 1.5 and above (from comment)

You can't. The shortest way to write it is:

ArrayList<String> list = myMap.get(key);
if (list == null)
    myMap.put(key, list = new ArrayList<String>());
list.add(element);

This is optimized to only perform one map lookup, unlike an implementation using containsKey() to detect if a new ArrayList is needed.

Except:

  1. Just write it all on a single line*:

    ArrayList<String> list = myMap.get(key); if (list == null) myMap.put(key, list = new ArrayList<String>()); list.add(element);
    

    * Yes, that's a joke, though technically a valid answer to the question.

  2. Create a helper method, e.g. in a shared utility class:

    public static <K, V> void addToMapList(Map<K, ArrayList<V>> mapList, K key, V value) {
        ArrayList<V> list = mapList.get(key);
        if (list == null)
            mapList.put(key, list = new ArrayList<V>());
        list.add(value);
    }
    

    Then using it is a single line:

    MyUtil.addToMapList(myMap, key, element);
    
  3. Use Apache Commons Collections ™* class MultiValueMap:

    MultiMap<String, String> myMap = new MultiValueMap<String, String>();
    
    myMap.put(key, element);
    

    * For Java 5, use version 4.0.

  4. Use Google Guava* class ArrayListMultimap:

    ListMultimap<String, String> myMap = ArrayListMultimap.create();
    
    myMap.put(key, element);
    

    * For Java 5, use version 11.0.

  5. Write your own MultiMap.

1 Comment

Unfortunately, i have to go with multiple lines..... as I cant change the Map to something else like ListMultimap
1

As you need a solution for Java 5, the best you could do is simplify this:

ArrayList<String> tmpArrList = new ArrayList<>();
tmpArrList.add(element);
myMap.put(key, tmpArrayList);

With this:

myMap.put(key, new ArrayList<String>(Collections.singletonList(element)));

Or the code allowing to add an entry to your map could be:

if (!myMap.containsKey(key)) {
    myMap.put(key, new ArrayList<String>());
}
myMap.get(key).add(element);

You could also consider using a Multimap from Google Guava but note that it is only stating from Java 6 for the most recent versions hopefully there are existing backports for Java 5 of the versions 13.0, 14.0, 16.0 and 17.0 available from here, more details here.

Here is an example of how to use it:

ListMultimap<String, String> myMap = ArrayListMultimap.create();
// This will map the provided key with the provided value whetever the
// total amount of values already mapped with this key  
myMap.put(key, element);

2 Comments

According to Guava's Release History: Releases 1.0 through 11.0 require JDK 1.5 or newer. Releases 12.0 through 20.0 require JDK 1.6 or newer. Since ArrayListMultimap was adding in 2.0, using version 11.0 should do it.
@Andreas the link that I provide, propose a backport of 13.0, 14.0, 16.0 and 17.0 which is even better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.