Нулевая проверка в усиленном цикле

Каков наилучший способ защиты от null в цикле 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, если она равна нулю, то не запускайте цикл?

Ответ 1

Вам лучше проверить, откуда вы взяли этот список.

Пустой список - это все, что вам нужно, потому что пустой список не будет терпеть неудачу.

Если вы получаете этот список из другого места и не знаете, нормально ли это или нет, вы можете создать метод утилиты и использовать его следующим образом:

for( Object o : safe( list ) ) {
   // do whatever 
 }

И, конечно, safe будет:

public static List safe( List other ) {
    return other == null ? Collections.EMPTY_LIST : other;
}

Ответ 2

Вы могли бы написать метод помощника, который возвратил пустую последовательность, если вы передали null:

public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
    return iterable == null ? Collections.<T>emptyList() : iterable;
}

Затем используйте:

for (Object object : emptyIfNull(someList)) {
}

Я не думаю, что на самом деле я это сделаю - я обычно использовал бы свою вторую форму. В частности, важно, чтобы "или выбросить ex" было важно - если оно действительно не должно быть нулевым, вы обязательно должны указать исключение. Вы знаете, что что-то пошло не так, но вы не знаете степень ущерба. Прервать рано.

Ответ 3

Это уже 2017, и теперь вы можете использовать Apache Commons Collections4

Использование:

for(Object obj : ListUtils.emptyIfNull(list1)){
    // Do your stuff
}

Вы можете выполнить ту же нуль-безопасную проверку в других классах Collection с помощью CollectionUtils.emptyIfNull.

Ответ 4

Если вы получаете этот List из вызова метода, который вы реализуете, не возвращайте null, верните пустой List.

Если вы не можете изменить реализацию, вы застряли с тегом null. Если это не должно быть null, тогда выведите исключение.

Я бы не пошел на вспомогательный метод, который возвращает пустой список, потому что он может быть полезен несколько раз, но затем вы привыкнете его вызывать в каждом цикле, который вы, возможно, скрываете некоторые ошибки.

Ответ 5

Я изменил приведенный выше ответ, поэтому вам не нужно отбрасывать из Object

public static <T> List<T> safeClient( List<T> other ) {
            return other == null ? Collections.EMPTY_LIST : other;
}

а затем просто вызовите Список

for (MyOwnObject ownObject : safeClient(someList)) {
    // do whatever
}

Explaination: MyOwnObject: Если List<Integer>, тогда MyOwnObject будет в этом случае целочисленным.

Ответ 6

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, но ради СУХОЙ мантры, я считаю, что стоит отметить. См. Страницу проекта commons-lang. Вот 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;
}

Ответ 7

С Java 8 Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
    // do whatever
}

Ответ 8

Еще один способ эффективно защитить от нуля в цикле for - это обернуть вашу коллекцию с помощью Google Guava Optional<T>, так как это надеется, дает возможность эффективно очистить коллекцию, поскольку ожидается, что клиент будет проверять наличие коллекции с помощью Optional.isPresent().

Ответ 9

Для любого, кто не заинтересован в написании собственного статического метода защиты от нуля, вы можете использовать: commons-lang org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object). Например:

    for (final String item : 
    (List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }

ObjectUtils.defaultIfNull JavaDoc

Ответ 10

Использовать метод CollectionUtils.isEmpty(Collection coll), который является Null-safe, если указанная коллекция пуста.

для этого import org.apache.commons.collections.CollectionUtils.

Зависимость от Maven

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

Ответ 11

for (Object object : someList) {

   // do whatever
}  throws the null pointer exception.