web-dev-qa-db-fra.com

Vérification nulle dans une boucle for améliorée

Quel est le meilleur moyen de se protéger contre null dans une boucle for en Java? 

Cela semble moche:

if (someList != null) {
    for (Object object : someList) {
        // do whatever
    }
}

Ou

if (someList == null) {
    return; // Or throw ex
}
for (Object object : someList) {
    // do whatever
}

Il pourrait ne pas y avoir d'autre moyen. Devraient-ils l'avoir mis dans la construction for elle-même, si elle est nulle alors ne lancez pas la boucle?

154
fastcodejava

Vous devriez mieux vérifier d'où vous tirez cette liste. 

Une liste vide est tout ce dont vous avez besoin, car une liste vide n'échouera pas.

Si vous obtenez cette liste ailleurs et que vous ne savez pas si c'est correct ou non, vous pouvez créer une méthode utilitaire et l'utiliser comme ceci:

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

Et bien sûr, safe serait:

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

Vous pourriez potentiellement écrire une méthode d'assistance qui renvoyait une séquence vide si vous passiez à null:

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

Alors utilisez:

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

Je ne pense toutefois pas que je ferais cela - j’utiliserais généralement votre deuxième formulaire. En particulier, le "ou le lancer de l'ex" est important - s'il ne devrait pas être nul, vous devriez absolument lancer une exception. Vous savez que quelque chose a mal tourné, mais vous ne connaissez pas l'étendue des dégâts. Abandonner tôt.

91
Jon Skeet

Nous sommes déjà en 2017 et vous pouvez maintenant utiliser Apache Commons Collections4

L'usage:

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

Vous pouvez effectuer la même vérification null-safe pour les autres classes Collection avec CollectionUtils.emptyIfNull.

23
Fred Pym

Si vous obtenez cette List à partir d'un appel de méthode que vous implémentez, ne renvoyez pas null, renvoyez une List vide.

Si vous ne pouvez pas modifier l'implémentation, alors vous êtes bloqué avec la vérification null. Si cela ne devrait pas être null, lancez une exception.

Je ne choisirais pas la méthode d'assistance qui renvoie une liste vide, car elle peut être utile à certains moments, mais vous vous habituez à l'appeler à chaque boucle que vous créez, masquant éventuellement des bogues.

7
Lombo

Utilisez ArrayUtils.nullToEmpty de la bibliothèque commons-lang pour les tableaux

for( Object o : ArrayUtils.nullToEmpty(list) ) {
   // do whatever 
}

Cette fonctionnalité existe dans la bibliothèque commons-lang, incluse dans la plupart des projets 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;
}

C’est la même chose que la réponse donnée par @OscarRyz, mais dans l’intérêt du SEC mantra, je crois que cela vaut la peine de le noter. Voir la page commons-lang project. Voici la nullToEmpty API documentation et source

Entrée Maven pour inclure commons-lang dans votre projet s'il ne l'est pas déjà. 

<dependency>
    <groupId>org.Apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

Malheureusement, commons-lang ne fournit pas cette fonctionnalité pour les types List. Dans ce cas, vous devrez utiliser une méthode d'assistance, comme mentionné précédemment.

public static <E> List<E> nullToEmpty(List<E> list)
{
    if(list == null || list.isEmpty())
    {
        return Collections.emptyList();
    }
    return list;
}
7
sdc

Avec Java 8 Optional:

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

J'ai modifié la réponse ci-dessus, vous n'avez donc pas besoin de lancer à partir d'un objet

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

puis appelez simplement la liste par

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

Explication: MyOwnObject: Si List<Integer>, alors MyOwnObject sera Integer dans ce cas.

3
Haris Iltifat

Pour ceux qui ne souhaitent pas écrire leur propre méthode de sécurité statique null, vous pouvez utiliser: org.Apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object) de commons-lang Par exemple: 

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

ObjectUtils.defaultIfNull JavaDoc

1
Jacob Briscoe

Une autre façon de se prémunir efficacement contre une valeur null dans une boucle for consiste à envelopper votre collection avec le code Optional<T> de Google Guava, car elle permet, espère-t-on, de clarifier la possibilité d’une collection réellement vide, le client la collection est présente avec Optional.isPresent().

1
Nico de Wet

Utilisez la méthode CollectionUtils.isEmpty(Collection coll) qui est Null-safe. Vérifiez si la collection spécifiée est vide. 

pour ce import org.Apache.commons.collections.CollectionUtils.

Dépendance Maven

<dependency>
    <groupId>org.Apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>
0
Swadeshi