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.

Я думал, что !checkList.isEmpty() вернет NPE. Я думал, что мне придется сделать checkList!= null && !checkList.isEmpty(), поэтому я использовал другую библиотеку. Итак, для этой проверки у меня должны быть вложенные операторы if ()?

adbdkb 21.05.2019 14:47

Что-то вроде 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]);, что нехорошо, если вы не знаете, почему эти жестко закодированные значения всплывают.

Naman 21.05.2019 14:54

Не позволяйте ссылкам на коллекции быть null в первую очередь. Тогда вам не нужны сторонние методы, выполняющие null проверки.

Holger 21.05.2019 16:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
2 115
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если 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("_");

        }
Ответ принят как подходящий

Вы можете использовать длинную цепочку операций 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 на ранней стадии, как только вы преобразовываете пользовательский ввод в объекты в памяти. Вам не нужно вставлять вызовы trim() и isBlank() и тому подобное повсюду.

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

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

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

Спасибо. Я согласен с тем, что не использую нулевые списки и карты, но... Я получаю эти данные из какой-то другой части системы, поэтому не могу их контролировать. Я попробую вышеизложенное с этим предположением и посмотрю, сработает ли оно для меня.

adbdkb 21.05.2019 15:45

Первый работал хорошо. Что касается второго, я пытаюсь работать с командой, которая создает список, чтобы увидеть, могут ли они внести изменения, чтобы обеспечить отправку пустых списков или карт вместо нуля. Второй также работал над тестовым случаем, где я гарантировал не иметь нулей в полученных данных.

adbdkb 21.05.2019 17:36

Не вставляйте 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) {
    ...
}

Другие вопросы по теме