views:

257

answers:

6

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.

A: 

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.

Brian Agnew
+3  A: 

Something like this?

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

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)) {
    }
}
Bozho
Thanks. This is what I needed. Do revise your answer though... I was looking for an ArrayList... I don't want you getting downvoted for a stupid reason :)
Hristo
@Hristo you get an `ArrayList`, but you reference it by its interface - `List`, which is considered a better practice (unless your really need the methods specific to `ArrayList`)
Bozho
If you need both the key and the value, you should use the entrySet, rather than the keySet and a get.
ILMTitan
@Bozho... oh interesting... I wasn't aware of that. Thanks!
Hristo
+2  A: 

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 (i.e. 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.

Andrzej Doyle
Wow... Thanks for that response! Quick question... when you say `Iterater<String> it = ...;`, is it equal to an element, in my case, is it equal to an element from the Set? Thanks for the link to 'for-each'. I've never used it. Stellar answer!
Hristo
Also... if we go back to your for loop... if I do find a match, how can I extract the name (key) of the ArrayList that contains 'sAccuser'?
Hristo
@Hristo - the `it` variable would be an object that would return successive elements of the underlying collection every time its `next()` method was called, not an element itself. As for your second question, I've modified my example to show it using `entrySet()`, as this is the way to iterate over a Map when you care about both keys *and* values.
Andrzej Doyle
@Andrzej... ahhh thanks!
Hristo
A: 

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);
Jes
@Jes... thanks for your response. I'm already writing a method that is doing this. This is the point of my question :) Quick question... when you say `Iterater<String> iterAccusers = ...;`, is iterAccusers equal to an element, in my case, is it equal to an element from the Set, or is it uninitialized to begin with?
Hristo
Also, one more question... if I do find a match, how can I extract the name (key) of the ArrayList that contains 'sAccuser' that it belongs to?
Hristo
iterAccusers is an Iterator i.e. you can call next() on it and get the next element. It's just like a for-each loop. The iterator is NOT an element in the set, it's an object used to iterate through the set.As for extracting the key. Instead of returning the list, just return the key. See the edited code.
Jes
@Jes... Thanks!
Hristo
A: 

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.

DeathB4Decaf
@DeathB4Decaf... what is an Entry object? I haven't encountered that yet.
Hristo
It's actually an inner Class of Map. The full class name is java.util.Map.Entry. (The JavaDoc is here: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Map.Entry.html) In my experience, it's seldom used. However, in this case it serves nicely, and since it's part of the Map API, there's no reason not to use it.
DeathB4Decaf