Suppose I have a map of given name, surname pairs and I want to find the given name of the first entry in that map that has the surname matching a certain value. How would we do this in a java 8 fashion.
In my test case example below I put two ways that would do it.
However the first one (looking for the given name of the first person with a surname of "Donkey") will throw java.util.NoSuchElementException: No value present so it is not safe.
The second one works but it is not only harder to read but it it is a bit not quite functional.
Just wondering if someone here would suggest me an easier clearer way of achieving this using either stream()
or forEach()
or both.
@Test
public void shouldBeAbleToReturnTheKeyOfTheFirstMatchingValue() throws Exception {
Map<String, String> names = new LinkedHashMap<>();
names.put("John", "Doe");
names.put("Fred", "Flintstone");
names.put("Jane", "Doe");
String keyOfTheFirst = names.entrySet().stream().filter(e -> e.getValue().equals("Doe")).findFirst().get().getKey();
assertEquals("John", keyOfTheFirst);
try {
names.entrySet().stream().filter(e -> e.getValue().equals("Donkey")).findFirst().get();
} catch (NoSuchElementException e){
// Expected
}
Optional<Map.Entry<String, String>> optionalEntry = names.entrySet().stream().filter(e -> e.getValue().equals("Donkey")).findFirst();
keyOfTheFirst = optionalEntry.isPresent() ? optionalEntry.get().getKey() : null;
assertNull(keyOfTheFirst);
}
Thank you in advance.
Get keys from value in HashMap To find all the keys that map to a certain value, we can loop the entrySet() and Objects. equals to compare the value and get the key. The common mistake is use the entry. getValue().
If your hashmap contain unique key to unique value mapping, you can maintain one more hashmap that contain mapping from Value to Key. In that case you can use second hashmap to get key.
To get the first element of a Map , use destructuring assignment, e.g. const [firstKey] = map. keys() and const [firstValue] = map. values() . The keys() and values() methods return an iterator object that contains the Map's keys and values.
Get Keys and Values (Entries) from Java MapThe entrySet() method returns a set of Map. Entry<K, V> objects that reside in the map. You can easily iterate over this set to get the keys and their associated values from a map.
To return a default value if there is no match, use Optional#orElse
names.entrySet().stream() .filter(e -> e.getValue().equals("Donkey")) .map(Map.Entry::getKey) .findFirst() .orElse(null);
From a similar question:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
return map.entrySet()
.stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
Then you can select the first, if you want to. Remember that the key
is unique, the value
is not.
Edit: The whole code (thanks @Peter Lawrey)
package test;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
public class Main {
public static void main(String[] args) {
Map<String, String> names = new LinkedHashMap<>();
names.put("John", "Doe");
names.put("Fred", "Flintstone");
names.put("Jane", "Doe");
Optional<String> firstKey = names.entrySet().stream()
.filter(entry -> Objects.equals(entry.getValue(), "Doe"))
.map(Map.Entry::getKey).findFirst();
if (firstKey.isPresent()) {
System.out.println(firstKey.get());
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With