adbdkb
adbdkb

Reputation: 2161

Java 8 nested null check for a string in a map in a list

I need to do a series of null checks ( nested null-checks ) to get an array of strings like below

String[] test;
if(CollectionUtils.isNotEmpty(checkList)){
    if(MapUtils.isNotEmpty(checkList.get(0))){
        if(StringUtils.isNotBlank(checkList.get(0).get("filename"))){
            test = checkList.get(0).get("filename").split("_");
        }
    }
}

Is there a better way, maybe using Java8 Optional, to perform these kind of nested checks? I unsuccessfully tried to use Optional with flatmap / map.

Upvotes: 3

Views: 3539

Answers (3)

Chirag Shah
Chirag Shah

Reputation: 373

If checkList is null, it will throw null pointer exception on CollectionUtils.isNotEmpty(checkList). Also use in-built empty checker. Better you should code

        if (null != checkList && !checkList.isEmpty() 
                && null != checkList.get(0) && !checkList.get(0).isEmpty()
                && StringUtils.isNotBlank(checkList.get(0).get("filename"))) {

            test = checkList.get(0).get("filename").split("_");

        }

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361585

You could use a long chain of Optional and Stream operations to transform the input step by step into the output. Something like this (untested):

String[] test = Optional.ofNullable(checkList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .findFirst()
    .map(m -> m.get("filename"))
    .filter(f -> !f.trim().isEmpty())
    .map(f -> f.split("_"))
    .orElse(null);

I'd strongly encourage you to stop using null lists and maps. It's a lot better to use empty collections rather than null collections, that way you don't have to have null checks all over the place. Furthermore, don't allow empty or blank strings into your collections; filter them out or replace them with null early, as soon as you're converting user input into in-memory objects. You don't want to have to insert calls to trim() and isBlank() and the like all over the place.

If you did that you could simplify to:

String[] test = checkList.stream()
    .findFirst()
    .map(m -> m.get("filename"))
    .map(f -> f.split("_"))
    .orElse(null);

Much nicer, no?

Upvotes: 4

Lino
Lino

Reputation: 19926

Don't nest the ifs, but just unwrap and invert them:

String[] defaultValue = // let this be what ever you want

if(checkList == null || checkList.isEmpty()) {
    return defaultValue;
}

Map<String, String> map = checkList.get(0);
if(map == null || map.isEmpty()) {
    return defaultValue;
}

String string = map.get("filename");
if(string == null || string.trim().isEmpty()) {
    return defaultValue;
}

return string.split("_");

Though this only works when you wrap this extraction logic in a method:

public static String[] unwrap(List<Map<String, String>> checkList) {
    ...
}

Upvotes: 1

Related Questions