Мне нужно выполнить серию нулевых проверок (вложенных нулевых проверок), чтобы получить массив строк, как показано ниже.
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.
Что-то вроде 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]);, что нехорошо, если вы не знаете, почему эти жестко закодированные значения всплывают.
Не позволяйте ссылкам на коллекции быть null в первую очередь. Тогда вам не нужны сторонние методы, выполняющие null проверки.




Если 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);
Гораздо приятнее, нет?
Спасибо. Я согласен с тем, что не использую нулевые списки и карты, но... Я получаю эти данные из какой-то другой части системы, поэтому не могу их контролировать. Я попробую вышеизложенное с этим предположением и посмотрю, сработает ли оно для меня.
Первый работал хорошо. Что касается второго, я пытаюсь работать с командой, которая создает список, чтобы увидеть, могут ли они внести изменения, чтобы обеспечить отправку пустых списков или карт вместо нуля. Второй также работал над тестовым случаем, где я гарантировал не иметь нулей в полученных данных.
Не вставляйте 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) {
...
}
Я думал, что
!checkList.isEmpty()вернет NPE. Я думал, что мне придется сделатьcheckList!= null && !checkList.isEmpty(), поэтому я использовал другую библиотеку. Итак, для этой проверки у меня должны быть вложенные операторыif ()?