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.
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);