I have Map<String, Map<String, String>> myMap in my Java 8 class. I need to navigate to a leaf String like myMap['keyA']['keyB'], returning null if either 'keyA' or 'keyB' does not exist in the correlating Map.
In groovy I would use myMap?.keyA?.keyB and be done with it. I understand that Java 8's Optional<T> brings similar behavior into java. Is there a way to use this new behavior to concisely mimic the groovy functionality? If not, is there another concise way to get this behavior in Java 8, or am I still stuck with elaborate procedural code?
String valueOrNull = Optional.ofNullable(myMap.get("keyA"))
.map(x -> x.get("keyB"))
.orElse(null);
First, it wraps the results of the first lookup in an Optional, which acts as a monad. If you add a third layer (myMap.?keyA.?keyB.?keyC), it would look like this:
String valueOrNull = Optional.ofNullable(myMap.get("keyA"))
.map(x -> x.get("keyB"))
.map(x -> x.get("keyC"))
.orElse(null);
You can use Optional's ofNullable method to create an Optional that may or may not represent a null value. Then you can use the map method that will, with a Function, map the result to a new value if the value wasn't already null.
Here, I supply a Function as a lambda expression to get the value from the second Map using the second key.
Optional<String> result = Optional.ofNullable(myMap.get("keyA")).map(m -> m.get("keyB"));
From there you can see if the Optional has a value with isPresent(), and if so, get it with get().
Testing:
public static Optional<String> method(Map<String, Map<String, String>> map,
String key1, String key2)
{
return Optional.ofNullable(map.get(key1)).map(m -> m.get(key2));
}
Calling Code:
Map<String, Map<String, String>> myMap = new HashMap<>();
Map<String, String> inner = new HashMap<>();
inner.put("one", "two");
myMap.put("three", inner);
System.out.println(method(myMap, "three", "one"));
System.out.println(method(myMap, "three", "dne"));
System.out.println(method(myMap, "dne", "dne"));
Output:
Optional[two]
Optional.empty
Optional.empty
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