Add in hashmap only if value is not null and not blank JAVA

Viewed 47

I have hashmap like below

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

I am trying to add values in it like below

attributes.put("Id", systemGeneratedDetails.get(0).getId());
attributes.put("Name", systemGeneratedDetails.get(0).getName());

but sometimes getId or getName will return null or blank. In that case I don't want to add it in map.

How to do it in Java?

2 Answers

The simplest way to do this would be to wrap the logic within an if-statement:


var details = systemGeneratedDetails.get(0);
var id = details.getId();
var name = details.getName();

if (id != null && !id.isBlank()) {
  attributes.put("Id", id);
}
if (name != null && !name.isBlank()) {
  attributes.put("Name", systemGeneratedDetails.get(0).getName());
}

Another interesting method of going about this is to use Optionals:

var details = Optional.of(systemGeneratedDetails.get(0));
var idOpt = details.map(YourDetailType::getId).filter(s -> !s.isBlank());
var nameOpt = details.map(YourDetailType::getName).filter(s -> !s.isBlank());

idOpt.ifPresent(id -> attributes.put("Id", id));
nameOpt.ifPresent(name -> attributes.put("Name", name));

Just make sure to replace YourDetailType with the actual type of systemGeneratedDetails.get(0).

Please keep in mind however, that this will create a bunch of extra objects (though the impact should be minimal thanks to JVM escape analysis), and that some programmers frown upon the practice of using Optionals as anything except for return values.

putIfAbsent() + replace()

You can use a combination Map.putIfAbsent() + three-args version of Map.replace():

attributes.putIfAbsent("id", systemGeneratedDetails.get(0).getId());
attributes.replace("id", "", systemGeneratedDetails.get(0).getId());

To avoid code-repetition, this logic can be extracted into a separate method and gentrified:

public static <K, V> void putIfNullOrEmpty(Map<K, V> map,
                                           K key, V oldValue, V newValue) {

    map.putIfAbsent(key, newValue);
    map.replace(key, oldValue, newValue);
}

Usage example:

putIfNullOrEmpty(attributes, "id", "", systemGeneratedDetails.get(0).getId());
putIfNullOrEmpty(attributes, "Name", "", systemGeneratedDetails.get(0).getId());

compute()

Another way to achieve that is by using Java 8 method Map.compute(), which expects a key and a remappingFunction responsible for generating the resulting value based on the key and existing value associated with the key:

attributes.compute("Id", (k, v) -> v == null || v.isEmpty() ? 
                         systemGeneratedDetails.get(0).getId() : v);

To avoid redundancy, you can extract this logic into a separate method and gentrify it:

public static <K, V> void putIf(Map<K, V> map,
                                Predicate<V> condition,
                                K key, V newValue) {
    
    map.compute(key, (k, v) -> condition.test(v) ? newValue : v);
}

Usage example:

Predicate<String> isNullOrEmpty = v -> v == null || v.isEmpty();
        
putIf(attributes, isNullOrEmpty, "id", systemGeneratedDetails.get(0).getId());
putIf(attributes, isNullOrEmpty, "Name", systemGeneratedDetails.get(0).getId());
Related