简体   繁体   中英

How can I extract ArrayList from HashMap and loop through it in Java?

I have set up a HashMap like so:

Map<String, ArrayList<String>> theAccused = new HashMap<String, ArrayList<String>>();

... and I populate this by storing for every name (key), a list of names (value). So:

ArrayList<String> saAccused = new ArrayList<String>();
// populate 'saAccused' ArrayList
...
// done populating
theAccused.put(sAccuser, saAccused);

So now, I want to look through all of the entries in the HashMap and see if (for each 'sAccuser'), the list 'saAccused' contains a certain name. This is my failed attempt so far:

Set<String> setAccusers = theAccused.keySet();
Iterator<String> iterAccusers = setAccusers.iterator();
iterAccusers.next();
ArrayList<String> saTheAccused;

// check if 'sAccuser' has been accused by anyone before
for (int i = 0; i < theAccused.size(); i++) {
    saTheAccused = theAccused.get(iterAccusers);

    if (saTheAccused.contains(sAccuser)) {

    }
    iterAccusers.next();
}

... however I'm not sure how the Set and Iterator classes work :/ The problem is that I don't have the "values"... the names... the 'sAccuser' s... for the HashMap available.

In a nutshell, I want to iterate through the HashMap and check if a specific name is stored in any of the lists. So how can I do this? Let me know if you need me to go into further detail or clear up any confusion.

Thanks.

In a nutshell, I want to iterate through the HashMap and check if a specific name is stored in any of the lists. So how can I do this?

There's two ways of iterating through the map that might be of interest here. Firstly, you can iterate through all of the mappings (ie pairs of key-value relations) using the entrySet() method, which will let you know what the key is for each arraylist. Alternatively, if you don't need the key, you can simply get all of the lists in turn via the values() method. Using the first option might look something like this:

for (Map.Entry<String, ArrayList<String>> entry : theAccused.entrySet())
{
   String sListName = entry.getKey();
   ArrayList<String> saAccused = entry.getValue();
   if (saAccused.contains(sAccuser))
   {
      // Fire your logic for when you find a match, which can
      // depend on the list's key (name) as well
   }
}

To answer the broader questions - the Set interface simply represents an (unordered) collection of non-duplicated values. As you can see by the linked Javadoc, there are methods available that you might expect for such an unordered collection. An Iterator is an object that traverses some data structure presenting each element in turn. Typical usage of an iterator would look something like the following:

Iterator<?> it = ...; // get the iterator somehow; often by calling iterator() on a Collection
while (it.hasNext())
{
   Object obj = it.next();
   // Do something with the obj
}

that is, check whether the iterator is nonexhausted (has more elements) then call the next() method to get that element. However, since the above pattern is so common, it can be elided with Java 5's foreach loop , sparing you from dealing with the iterator itself, as I took advantage of in my first example.

Something like this?

for (List<String> list : theAccused.values()) {
    if (list.contains("somename")) {
        // found somename
    }
}

This should make it work:

saTheAccused = theAccused.get(iterAccused.next());

However, to make your code more readable, you can have either:

for (List<String> values : theAccused.values()) {
    if (value.contains(sAcuser)) {
       ..
    }
}

or, if you need the key:

for (String key : theAccused.keySet()) {
    List<String> accused = theAccused.get(key);
    if (accused.contains(sAccuser)) {
    }
}

You need to use the value from Iterator.next() to index into the Map .

String key = iterAccusers.next();
saTheAccused = theAccused.get(key);

Currently you're getting values from the Map based on the iterator , not the values returned by the iterator.

Make a method that does it:

 private String findListWithKeyword(Map<String, ArrayList<String>> map, String keyword) {
   Iterator<String> iterAccusers = map.keySet().iterator();
   while(iterAccusers.hasNext()) {
      String key = iterAccusers.next();
      ArrayList<String> list = theAccused.get(key);
      if (list.contains(keyword)) {
         return key;
      } 
   }
}

And when you call the method:

String key = findListWithKeyword(map, "foobar");
ArrayList<String> theCorrectList = map.get(key);

It sounds like you need to do two things: first, find out if a given name is "accused", and second, find out who the accuser is. For that, you need to iterate over the Entry objects within your Map.

    for (Entry<String, List<String>> entry : theAccused.entrySet()) {
        if (entry.getValue().contains(accused)) {
            return entry.getKey();
        }
    }

    return null; // Or throw NullPointerException, or whatever.

In this loop, the Entry object holds a single key-value mapping. So entry.getValue() contains the list of accused, and entry.getKey() contains their accuser.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM