Thao Nguyen
Thao Nguyen

Reputation: 901

HashMap updating ArrayList

I'm just starting to learn to use HashMap and reading the java tutorial, but I'm having trouble.

I'm trying to update the List inside a HashMap but I want to get the List of that key, is there a way to update a specific List of the key instead of having to make...5 different Lists and updating those?

 HashMap<String, ArrayList<String>> mMap = new HashMap<String, ArrayList<String>>();
        ArrayList<String> list = new ArrayList<String>();
        mMap.put("A", list);
        mMap.put("B", list);
        mMap.put("C", list);
        mMap.put("D", list);

        Iterator iter = mMap.entrySet().iterator();

        if (mMap.containsKey("A"))
        {   
            Map.Entry mEntry = (Map.Entry) iter.next();
            list.add("test");
            mMap.put("A",list);
            System.out.println(mEntry.getKey() + " : " + mEntry.getValue());
        }
        else if (mMap.containsKey("B"))
        {   
            Map.Entry mEntry = (Map.Entry) iter.next();
            list.add("entry");
            mMap.put("B",list);
            System.out.println(mEntry.getKey() + " : " + mEntry.getValue());
        }

Upvotes: 11

Views: 35934

Answers (6)

rahul sharma
rahul sharma

Reputation: 509

I would do something like this.

private final ReentrantLock lock = new ReentrantLock();
    Map<String ,List<String>> mMap=new HashMap<>();
    public  void myAdd(String key, String value) {
        try {
            lock.lock();
        List<String> there =mMap.get(key)==null?new ArrayList<>():mMap.get(key);
        there.add(value);
        mMap.put(key, there);
        }finally {
            lock.unlock();
        }
    }

Upvotes: 1

user949300
user949300

Reputation: 15729

  1. Like @Tudor said, use mMap.get("A").add("foo");

  2. You put the same exact list into each map entry. You initial lines should be

    mMap.put("A", new ArrayList());
    mMap.put("B", new ArrayList()); 
    ...
    mMap.put("Z", new ArrayList());

Alternatvely, write a method that checks on the fly

public synchronized void myAdd(String key, String value) {
   List<String> there = mMap.get(key);
   if (there == null) {
      there = new ArrayList<String>();
      mMap.put(key, there);
   }
   there.add(value);
}

Upvotes: 7

Grzegorz Rożniecki
Grzegorz Rożniecki

Reputation: 28005

I think that in your case you can use Google Guava's Multimap and ListMultimap interfaces and ArrayListMultimap implementation.

Choosing right collection (in link there are only standard collections but Multimap is right in this case) makes code more readable:

ListMultimap<String, String> myMultimap = ArrayListMultimap.create();
myMultimap.put("A", "test");
myMultimap.put("B", "entry");

then myMultimap.get("A") gives you list (ArrayList instance in fact) with one element: "test", while myMultimap.get("C") gives you empty list.

Comparing to Map<String, List<String>> approach:

  • you don't have to initialize "C" key with empty list for it,
  • you don't have nulls checks (no NullPointerExceptions),
  • you don't have to do other checks such as myMap.containsKey("A"),
  • you write less code,
  • so your code is less bug-prone,
  • etc., etc.

P.S. Instead of:

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

use interfaces, not classes when using collections i.e.:

Map<String, List<String>> mMap = new HashMap<String, List<String>>();

and even better Guava's "static constructors" (you don't repeat code):

Map<String, List<String>> mMap = Maps.newHashMap()

when knowledge about implementation is not necessary.

Upvotes: 2

Paul Rubel
Paul Rubel

Reputation: 27222

If you add the same list as a value with different keys, in your case keys A,B,C, and D all point to the same list, and access and update the list through one key the changes will then be visible in all the lists. Each key points to the same list structure.

If you want the lists to be different you need to use different for different keys you need to use a different list.

You could automate the process, say by making your own insert method that clones the given list.

Upvotes: 1

aishwarya
aishwarya

Reputation: 1986

you probably mean:

HashMap<String, List<String>> mMap = new HashMap<String, List<String>>();
    mMap.put("A", new ArrayList<String>());
    mMap.put("B", new ArrayList<String>());
    mMap.put("C", new ArrayList<String>());
    mMap.put("D", new ArrayList<String>());

    if (mMap.containsKey("A"))
    {   
        mMap.get("A").add("test");
        System.out.println(mEntry.getKey() + " : " + mEntry.getValue());
    }
    else if (mMap.containsKey("B"))
    {   
        mMap.get("B").add("entry");
        System.out.println(mEntry.getKey() + " : " + mEntry.getValue());
    }
   ...

I wonder if you really need those containsKey checks either! HTH!

Upvotes: 2

Tudor
Tudor

Reputation: 62439

You could use something like:

mMap.get("A").add("test");
mMap.get("B").add("entry");

Upvotes: 24

Related Questions