Нулевая проверка в усиленном цикле
Каков наилучший способ защиты от 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.