Проверка нуля в расширенном цикле 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())) { ... }

ObjectUtils.defaultIfNull JavaDoc

Еще один способ эффективно защититься от нуля в цикле 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.
Другие вопросы по тегам