Есть ли способ избежать проверки на ноль перед началом итерации цикла for-each? - PullRequest
101 голосов
/ 21 мая 2011

Каждый раз, когда мне приходится перебирать коллекцию, я заканчиваю проверку на нулевое значение, как раз перед началом итерации цикла for-each. Как это:

if( list1 != null ){
    for(Object obj : list1){

    }
}

Есть ли более короткий путь, чтобы мы могли избежать записи блока if? Примечание: я использую Java 5, и на некоторое время застряну с ней.

Ответы [ 9 ]

77 голосов
/ 21 мая 2011

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

null коллекции - плохая практика (по этой причине); вы должны использовать пустые коллекции вместо этого. (например, Collections.emptyList())

В качестве альтернативы, вы можете создать класс-оболочку, который реализует Iterable и принимает коллекции и обрабатывает коллекцию null.
Вы могли бы тогда написать foreach(T obj : new Nullable<T>(list1))

40 голосов
/ 21 мая 2011
public <T extends Iterable> T nullGuard(T item) {
  if (item == null) {
    return Collections.EmptyList;
  } else {
    return item;
  }
}

позволит вам написать

for (Object obj : nullGuard(list)) {
  ...
}

Конечно, это действительно просто перемещает сложность в другое место.

32 голосов
/ 22 мая 2011

Полагаю, правильный ответ таков: нет способа сделать его короче.Есть некоторые методы, такие как те в комментариях, но я не вижу себя использующим их.Я думаю, что лучше написать блок «если», чем использовать эти методы.и да .. прежде чем кто-либо еще упомянет об этом :) "в идеале" код должен быть разработан таким образом, чтобы список никогда не был null

17 голосов
/ 18 мая 2017

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

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

for(Object obj : CollectionUtils.emptyIfNull(list1)){
    // Do your stuff
}
16 голосов
/ 12 декабря 2014

В Java 8 есть другое решение, доступное с использованием java.util.Optional и ifPresent -метода.

Optional.ofNullable(list1).ifPresent(l -> l.forEach(item -> {/* do stuff */}));

Таким образом, это не решение для точной проблемы, но это единственное и, возможно, более элегантное решение.

12 голосов
/ 06 декабря 2013

Проверка нуля в расширенном цикле

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

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

for (Object object : emptyIfNull(someList)) { ... }
10 голосов
/ 23 февраля 2016

Apache Commons

for (String code: ListUtils.emptyIfNull(codes)) {

}           

Google Guava

for (String code: Optional.of(codes).get()) {

}
7 голосов
/ 21 мая 2011

Насколько короче вы хотите, чтобы это было?Это всего лишь дополнительные 2 строки И это ясная и лаконичная логика.

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

5 голосов
/ 21 мая 2011

1) если list1 является членом класса, создайте список в конструкторе, чтобы он был и не был нулевым, хотя и пустым.

2) для (Object obj: list1! = Null? List1: new ArrayList ())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...