Java 8 extract non null and non empty value from HashMap

Viewed 25038

Let consider a below HashMap

HashMap<String, String> map = new HashMap<String, String>();

I have values in map like

map.put("model", "test");

Currently, if I want to get value from map I am doing

if(map!=null){
 if(map.get("model")!=null && !map.get("model").isEmpty()){
   //some logic
 }
}

Is there any better approach in Java 8 by using Optional or Lambdas to achieve the above condition?

5 Answers

First of all, your Map should not be null. Never. It could be empty, but there's no reason for it to be null. So that eliminates the first null check.

Now, unfortunately, Java doesn't have such a utility method, but several commonly used libs (apache commons, Guava, etc.) have it, or you can write it yourself, so it becomes:

String model = map.get("model");
if (!Strings.isEmptyOrNull(model)) {
    // do somthing
}

Using Optional to wrap a nullable value as part of your logic is considered an antipattern. Optional is designed to be used as a return type. So I wouldn't advide using it here.

Also note that it feels like you're using a map to store attributes of an object If it is so, then consider defining a real class, with typed properties, instead of using a map.

Not sure why you check if the map is null after just having created it, but here goes:

Optional.ofNullable(map)
    .map(m -> m.getOrDefault("model", "")) // Use an empty String if not present
    .filter(s -> !s.isEmpty())             // Filter all empty values
    .ifPresent(valueString -> {            // Check if value is present
        // Logic here
});

Or in one line:

Optional.ofNullable(map).map(m -> m.getOrDefault("model", "")).filter(s -> !s.isEmpty()).ifPresent(valueString -> {
        // Logic here
});

Change ifPresent to map if you want to return something; i.e. Optional of whatever you calculate.

If you are interested in an Optional approach,

You can wrap a map.get("model") value into an Optional.ofNullable and do filter work by the Predicate<String> value -> !value.isEmpty():

if (isNull(map)) { // import static java.util.Objects.isNull;
    return;        // to minimise nesting
}

Optional.ofNullable(map.get("model"))
        .filter(value -> !value.isEmpty())
        .ifPresent(value -> { ... });

If you've declared map as showing in your sample code then it won't be null and you don't need to check for it. If you want to make sure then add an assertion:

assert map != null;

Given you are testing for empty strings, a possible approach is to use the empty string as a default if the key is not present:

if (!map.getOrDefault("model", "").isEmpty()) {
    ...
}

I think it's a shame that there was no method added to Map that returns an Optional rather than a null if the key isn't present. Something like:

map.getOptional("model").filter(v -> !v.isEmpty()).ifPresent(v -> {
    ...
}

While optionals have been added there's been little rework of older APIs to deprecate methods that return null to mean "not present".

You can also try containsKey method. For example:

HashMap<String, String> map = new HashMap<String, String>();
map.put("model", "test");

 if(map.containsKey("model")){
   //some logic
 }
Related