it-swarm.com.ru

Проверка нуля в расширенном цикле 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, если он равен null, не запускать цикл?

154
fastcodejava

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

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

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

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

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

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

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

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

Тогда используйте:

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

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

91
Jon Skeet

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

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

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

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

23
Fred Pym

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

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

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

7
Lombo

Используйте 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, но ради DRY мантры, я думаю, это стоит отметить. Смотрите 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
sdc

С Java 8 Optional:

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

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

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 в этом случае.

3
Haris Iltifat

Для тех, кто не заинтересован в написании своего собственного статического нулевого метода безопасности, вы можете использовать: 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

1
Jacob Briscoe

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

1
Nico de Wet

Используйте метод 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>
0
Swadeshi