Consider the following:
for (Boolean i: x.values()) {
if (i == false) {
return // KEY;
}
}
In the above code, I am trying to iterate through the HashMap
. And I want to return a Key when the value is false
.
How can I do it?
CodePudding user response:
You need to loop through the HashMap's entrySet
:
for (Map.Entry<Object, Boolean> entry : x.entrySet()) {
if(entry.getValue()){
return entry.getKey();
}
}
CodePudding user response:
In order to find first a key that is mapped to a particular value you need to iterate either over the key set or over the entry set.
The latter option is preferred because at each iteration step you will have a key-value pair on your hands. Therefore, it would be slightly faster than interrogating the map at every iteration (remainder: there could be collisions in a real hashmap, and finding the target node can take more time than accessing the value on a map-entry).
But you definitely can't use a collection of map values returned by a method values()
like you're doing in the code-snippet you've posted. There's no fast way of retrieving a key when you have only a value on your hands.
In the example below, ill show how to obtain a key from a map of arbitrary type that matches the condition (a Predicate
) provided dynamically at runtime using Stream API.
There's one important thing to consider: target value might not be present in the map. And the code should handle this case. We can provide a default value (either directly or via Supplier
), throw an exception (if according to the application logic the given value is always expected to be present), or by utilizing methods ifPresent()
, ifPresentOrElse()
provided by the Optional
class. In the example below, I've chosen to provide a default value.
Take a look at these tutorials for more information on lambda expressions and streams
public static void main(String[] args) {
Map<String, Boolean> sourceMap =
Map.of("A", true, "B", false, "C", true);
String result = getFirstKey(sourceMap, entry -> !entry.getValue(), "");
System.out.println(result);
}
public static <K, V> K getFirstKey(Map<K, V> map,
Predicate<Map.Entry<K, V>> condition,
K defaultKey) {
return map.entrySet().stream()
.filter(condition) // Stream<Map.Entry<K, V>>
.findFirst() // Optional<Map.Entry<K, V>>
.map(Map.Entry::getKey) // Optional<K>
.orElse(defaultKey); // or apply .orElseThrow() depending on your needs
}
Output
B // key assosiated with a value of `false`