Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to find if map contains any of the keys from a list/iterable

I need to check if a map contains any of the keys from a list, and if it does then return the first matching value. The naive approach that comes to mind is to do it in two nested loops:

Map<String, String> fields = new HashMap<String, String>();
fields.put("a", "value a");
fields.put("z", "value z");
String[] candidates = "a|b|c|d".split("|");
for (String key : fields.keySet()){
    for (String candidate : candidates) {
        if (key.equals(candidate)){
            return fields.get(key);
        }
    }
}

Is there a nicer and more efficient way, possibly one relying on the Java standard library?

like image 812
ccpizza Avatar asked Dec 28 '12 11:12

ccpizza


People also ask

How do you check if a map contains a key?

containsKey() method is used to check whether a particular key is being mapped into the HashMap or not. It takes the key element as a parameter and returns True if that element is mapped in the map.

How do you check if a map already contains a key in C++?

To check for the existence of a particular key in the map, the standard solution is to use the public member function find() of the ordered or the unordered map container, which returns an iterator to the key-value pair if the specified key is found, or iterator to the end of the container if the specified key is not ...

Which method will test if a key exists in a map object?

To check if a key exists in a Map , call the has() method on the Map , passing it the name of the key as a parameter. The has method returns true if the specified key exists in the Map , otherwise it returns false .


5 Answers

for(String candidate : candidates) {
 if(fields.containsKey(candidate)) {
  return fields.get(candidate)
 }
}

the best way if null values are possibly in map, and if only the first detected key is required.

like image 78
NimChimpsky Avatar answered Sep 21 '22 04:09

NimChimpsky


Surely something like:

for (String candidate : candidates) {
     String result = fields.get(key);
     if (result != null) {
         return result;
     }
}

The above only performs one map lookup per candidate key. It avoids the separate test for presence plus extraction, since extracting a non-existant key will simply give you a null. Note (thanks Slanec) that a null value for a valid key is indistinguishable from a non-existant key for this solution.

I don't quite understand why you're performing the case conversion, btw.

like image 30
Brian Agnew Avatar answered Sep 19 '22 04:09

Brian Agnew


In Java 8 you can have this:

boolean exists = Arrays.stream(candidates).anyMatch(fields::containsKey);

If you just want to know if any of candidates is key to the map.

If you want to know the first or any you can use:

Arrays.stream(candidates).filter(fields::containsKey).findAny();

or

Arrays.stream(candidates).filter(fields::containsKey).findFirst();

As per @Klapsa2503 answer above

like image 30
mrossini Avatar answered Sep 20 '22 04:09

mrossini


My take:

Map<String, String> fields = new HashMap<String, String>();
fields.put("a", "value a");
fields.put("z", "value z");
String[] candidates = "a|b|c|d".split("|");
for (String candidate : candidates) {
    if (fields.containsKey(candidate)) {
        return fields.get(candidate);
    }
}
like image 44
Petr Janeček Avatar answered Sep 17 '22 04:09

Petr Janeček


In Java 8 you can use this:

return candidates.stream()
            .filter(fields::containsKey)
            .findFirst()
            .map(fields::get)
            .orElse(null);
like image 22
Klapsa2503 Avatar answered Sep 18 '22 04:09

Klapsa2503