Java 8 вложенная проверка null для строки на карте в списке

Мне нужно выполнить серию нулевых проверок (вложенных нулевых проверок), чтобы получить массив строк, как показано ниже.

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("_");
        }
    }
}

Есть ли лучший способ, возможно, используя Java8 Optional, для выполнения таких вложенных проверок? Я безуспешно пытался использовать Optional с flatmap/map.


person adbdkb    schedule 21.05.2019    source источник
comment
Я думал, что !checkList.isEmpty() вернет NPE. Я думал, что мне придется сделать checkList!= null && !checkList.isEmpty(), поэтому я использовал другую библиотеку. Итак, для этой проверки я должен иметь вложенные операторы if()?   -  person adbdkb    schedule 21.05.2019
comment
Что-то вроде return Optional.ofNullable(checkList) .filter(l -> !l.isEmpty()) .map(l -> l.get(0)) .filter(m -> !m.isEmpty()) .map(e -> e.getOrDefault("filename", "").split("_")) .orElse(new String[10]);, что нехорошо, если вы не знаете, почему эти жестко закодированные значения плавают.   -  person Naman    schedule 21.05.2019
comment
Не позволяйте ссылкам на коллекции быть null в первую очередь. Тогда вам не нужны сторонние методы, выполняющие null проверки.   -  person Holger    schedule 21.05.2019


Ответы (3)


Вы можете использовать длинную цепочку операций Optional и Stream для пошагового преобразования входных данных в выходные данные. Что-то вроде этого (не проверено):

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);

Я настоятельно рекомендую вам прекратить использование null списков и карт. Гораздо лучше использовать пустые коллекции, а не null коллекции, таким образом, вам не нужно везде проверять нулевые значения. Кроме того, не допускайте пустых или пустых строк в свои коллекции; отфильтруйте их или замените на null заранее, как только вы преобразовываете пользовательский ввод в объекты в памяти. Вам не нужно вставлять вызовы trim() и isBlank() и тому подобное повсюду.

Если бы вы это сделали, вы могли бы упростить до:

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

Гораздо приятнее, нет?

person John Kugelman    schedule 21.05.2019
comment
Спасибо. Я согласен с тем, что не использую нулевые списки и карты, но... Я получаю эти данные из какой-то другой части системы, поэтому не могу их контролировать. Я попробую вышеизложенное с этим предположением и посмотрю, сработает ли оно для меня. - person adbdkb; 21.05.2019
comment
Первый работал хорошо. Что касается второго, я пытаюсь работать с командой, которая создает список, чтобы узнать, могут ли они внести изменения, чтобы обеспечить отправку пустых списков или карт вместо нуля. Второй также работал над тестовым случаем, где я гарантировал не иметь нулей в полученных данных. - person adbdkb; 21.05.2019

Не вставляйте if, а просто разворачивайте и инвертируйте их:

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("_");

Хотя это работает только тогда, когда вы заключаете эту логику извлечения в метод:

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

Если checkList имеет значение null, будет выдано исключение нулевого указателя для CollectionUtils.isNotEmpty(checkList). Также используйте встроенную пустую проверку. Лучше бы ты закодировался

        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("_");

        }
person Chirag Shah    schedule 21.05.2019