简体   繁体   中英

Java - Iterating over a Map which contains a List

First time here so I hope this makes sense!

I have a Map which contains a String as it's Key, and a List of Strings as it's Value. I need to iterate over all vlaues contained within each List within the Map.

So, first I want to get the Keys, which works:

Set<String> keys = theMap.keySet();

This returns me a Set containing all my Keys. Great:)

This is where I've got stuck - most of the info on the web seems to assume that the values I'd want returned from the Key would be a simple String or Integer, not another Set, or in this case a List. I tried theMap.values() but that didn't work, and I tried a forloop / for:eachloop, and neither of those did the trick.

Thanks y'all!

for(List<String> valueList : map.values()) {
  for(String value : valueList) {
    ...
  }
}

That's really the "normal" way to do it. Or, if you need the key as well...

for(Map.Entry<String, List<String>> entry : map.entrySet()) {
  String key = entry.getKey();
  for (String value : entry.getValue()) {
    ...
  }
}

That said, if you have the option, you might be interested in Guava's ListMultimap , which is a lot like a Map<K, List<V>> , but has a lot more features -- including a Collection<V> values() that acts exactly like what you're asking for, "flattening" all the values in the multimap into one collection. (Disclosure: I contribute to Guava.)

I recommend iterating over Map.entrySet() as it is faster (you have both, the key and the value, found in one step).

Map<String, List<String>> m = Collections.singletonMap(
    "list1", Arrays.asList("s1", "s2", "s3"));

for (Map.Entry<String, List<String>> me : m.entrySet()) {
  String key = me.getKey();
  List<String> valueList = me.getValue();
  System.out.println("Key: " + key);
  System.out.print("Values: ");
  for (String s : valueList) {
    System.out.print(s + " ");
  }
}

Or the same using the Java 8 API (Lambda functions):

m.entrySet().forEach(me -> {
    System.out.println("Key: " + me.getKey());
    System.out.print("Values: ");
    me.getValue().forEach(s -> System.out.print(s + " "));
});

Or with a little bit of Java Stream API mapping hardcore and method reference:-)

m.entrySet().stream().map(me -> {
    return "Key: " + me.getKey() + "\n"
        + "Values: " + me.getValue().stream()
            .collect(Collectors.joining(" "));
    })
    .forEach(System.out::print);

And the output is, as expected:

Key: list1
Values: s1 s2 s3 

You need a Map<String, List<String>>

The left hand side String is the key, the right hand side List<String> is the value, which in this case is a List of String s

Another example with the Java 8 API (lambda function).
When you want to iterate over:

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

theMap.forEach((key, value) -> {
       System.out.println("KEY: " + key);
       System.out.print("VALUES: ");
       value.forEach(System.out::println);
});

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