Проверка нуля в расширенном цикле for
Каков наилучший способ защиты от нуля в цикле for в Java?
Это кажется уродливым
if (someList != null) {
for (Object object : someList) {
// do whatever
}
}
Или же
if (someList == null) {
return; // Or throw ex
}
for (Object object : someList) {
// do whatever
}
Там не может быть никакого другого пути. Должны ли они положить его в for
построить себя, если это ноль, то не запустить цикл?
11 ответов
Вам лучше проверить, откуда вы получили этот список.
Пустой список - это все, что вам нужно, потому что пустой список не подведет.
Если вы получили этот список откуда-то еще и не знаете, в порядке ли он, вы можете создать служебный метод и использовать его следующим образом:
for( Object o : safe( list ) ) {
// do whatever
}
И конечно safe
было бы:
public static List safe( List other ) {
return other == null ? Collections.EMPTY_LIST : other;
}
Вы могли бы потенциально написать вспомогательный метод, который возвращал бы пустую последовательность, если вы передали в null:
public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
return iterable == null ? Collections.<T>emptyList() : iterable;
}
Тогда используйте:
for (Object object : emptyIfNull(someList)) {
}
Я не думаю, что на самом деле сделал бы это - я бы обычно использовал вашу вторую форму. В частности, важно "или throw ex" - если оно действительно не должно быть нулевым, вы должны обязательно выбросить исключение. Вы знаете, что что- то пошло не так, но вы не знаете масштаб ущерба. Прервать рано.
Уже 2017 год, и теперь вы можете использовать Apache Commons Collections4
Использование:
for(Object obj : ListUtils.emptyIfNull(list1)){
// Do your stuff
}
Вы можете сделать ту же проверку на нулевую безопасность для других классов Collection с помощью CollectionUtils.emptyIfNull
,
С Java 8 Optional
:
for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
// do whatever
}
TL;DR Использование ArrayUtils.nullToEmpty
от commons-lang
библиотека для массивов
for( Object o : ArrayUtils.nullToEmpty(list) ) {
// do whatever
}
Эта функциональность существует в commons-lang
библиотека, которая входит в большинство проектов Java.
// ArrayUtils.nullToEmpty source code
public static Object[] nullToEmpty(final Object[] array) {
if (isEmpty(array)) {
return EMPTY_OBJECT_ARRAY;
}
return array;
}
// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
return array == null || array.length == 0;
}
Это то же самое, что ответ @OscarRyz, но ради СУХОЙ мантры, я полагаю, это стоит отметить. См. Страницу проекта " Общие достояния ". Здесь nullToEmpty
API документация и источник
Maven запись, чтобы включить commons-lang
в вашем проекте, если его еще нет.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
К несчастью, commons-lang
не предоставляет эту функциональность для List
типы. В этом случае вам придется использовать вспомогательный метод, как упоминалось ранее.
public static <E> List<E> nullToEmpty(List<E> list)
{
if(list == null || list.isEmpty())
{
return Collections.emptyList();
}
return list;
}
Если вы получаете это List
из вызова метода, который вы реализуете, то не возвращайте null
вернуть пустое List
,
Если вы не можете изменить реализацию, то вы застряли с null
проверять. Если это не должно быть null
, а затем выбросить исключение.
Я бы не стал использовать вспомогательный метод, который возвращает пустой список, потому что он может быть полезен несколько раз, но тогда вы привыкнете вызывать его в каждом цикле, который вы делаете, возможно, скрывая некоторые ошибки.
Я изменил приведенный выше ответ, поэтому вам не нужно приводить из объекта
public static <T> List<T> safeClient( List<T> other ) {
return other == null ? Collections.EMPTY_LIST : other;
}
а затем просто вызвать список по
for (MyOwnObject ownObject : safeClient(someList)) {
// do whatever
}
Объяснение:
MyOwnObject: Если List<Integer>
тогда MyOwnObject будет Integer в этом случае.
Для тех, кто не заинтересован в написании собственного метода защиты от статического нуля, вы можете использовать: commons-lang's org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)
, Например:
for (final String item :
(List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }
Еще один способ эффективно защититься от нуля в цикле for - это обернуть вашу коллекцию с помощью Google Guava. Optional<T>
поскольку это, как мы надеемся, делает ясной возможность фактически пустой коллекции, так как клиент должен будет проверить, присутствует ли коллекция с Optional.isPresent()
,
Использование, CollectionUtils.isEmpty(Collection coll)
метод, который является нулевым-безопасным, проверяет, является ли указанная коллекция пустой.
за это import org.apache.commons.collections.CollectionUtils
,
Maven зависимость
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
for (Object object : someList) {
// do whatever
} throws the null pointer exception.