Home > Software engineering >  Using Java 8 Optional for safe fetching from Map
Using Java 8 Optional for safe fetching from Map

Time:03-26

I have a nullable Map<String, String> myMap in my Java 8 class.

I need to fetch a value from the map based on the following condition.

  • get keyA;
  • if not present, get keyB;
  • if not present, get keyC.

I understand that Java 8's Optional<T> brings the required behavior. Is there a way to use Optional to elegantly get the data instead of using containsKey checks?

CodePudding user response:

Building on Alexander Ivanchenko's answer, you could get the first non-null value from the map based on a series of alternate keys:

public static Optional<String> getValue(Map<String, String> map,
                                        String keyA, String... keys) {
    Optional<String> result = Optional.ofNullable(map.get(keyA));
    for (String key : keys) {
        if (result.isPresent()) break;
        result = result.or(() -> Optional.ofNullable(map.get(key)));
    }
    return result;
}

You could use the getOrDefault method of map, but something like

map.getOrDefault("keyA", map.getOrDefault("keyB", map.get("keyC")))

seems overly specific and complicated, and you still have to deal with the fact that neither keyA nor keyB nor keyC might be present, so you might still get null, and this has the performance penalty of looking up all three values from the map no matter which is returned.

It also only works for three keys.

CodePudding user response:

No. There is no special integration of Optional with Maps.

More to the point, Optional does not support null values. Assuming that by "nullable map" you mean "a map that can contain null values", you can't possibly use Optional to distinguish between "null values that are in your map" and "values that aren't in your map at all." There is absolutely no way to use Optional helpfully in this scenario.

CodePudding user response:

You can get an Optional result of retrieving the value corresponding to one of the given keys from a Map containing nullable values by using Stream.ofNullable() and Optional.or().

Method Optional.or() expects a supplier of Optional which will be utilized only if this method was invoked on an empty optional.

public static Optional<String> getValue(Map<String, String> myMap,
                                        String keyA, String keyB, String keyC) {
    
    return Stream.ofNullable(myMap) // precaution for myMap == null
            .flatMap(map -> Stream.ofNullable(map.get(keyA)))
            .findFirst()
            .or(() -> Optional.ofNullable(myMap.get(keyB)))   // evaluated only if keyA is not present
            .or(() -> Optional.ofNullable(myMap.get(keyC)));  // evaluated only if both keyA and keyB are not present                
}
  • Related