2010-02-12 29 views
137

¿Cuál es la mejor manera de protegerse de un bucle nulo en Java?Comprobación nula en un bucle forzado mejorado

Esto parece fea:

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

O

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

Puede que no haya ninguna otra manera. ¿Deberían haberlo puesto en el constructo for, si es nulo, entonces no ejecutar el ciclo?

+2

Usted es probablemente mejor de lanzar una NPE. 'null' no es lo mismo que una colección vacía. –

+6

@GregMattes ¿Cómo la pregunta de febrero es un duplicado de la pregunta de octubre? – Val

+1

Solo necesito usar Collections.nonNullElementsIn (...): http://stackoverflow.com/a/34913556/5637185 –

Respuesta

196

Debería verificar mejor de dónde obtiene esa lista.

Una lista vacía es todo lo que necesita, porque una lista vacía no fallará.

Si obtiene esta lista de otro lugar y no saben si está bien o no se puede crear un método de utilidad y utilizar de esta manera:

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

Y, por supuesto safe sería:

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

Tenga en cuenta que Collections.emptyList() evitará la asignación de un objeto adicional (IIRC). –

+7

@Jon: Siempre me he preguntado, ¿para qué sirve 'emptyList' http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#emptyList () ¿Qué es IIRC? – OscarRyz

+10

IIRC = "Si recuerdo correctamente". Y sí, hay una instancia singleton que se devuelve para todas las llamadas a Collections.emptyList(). – ColinD

81

Usted podría escribir un método auxiliar que devuelve una secuencia vacía si aprobó en nulo:

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

A continuación, utilice:

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

no creo que en realidad haría eso sin embargo, usualmente usaría tu segunda forma. En particular, el "o throw ex" es importante; si realmente no debería ser nulo, definitivamente debes lanzar una excepción. Usted sabe que algo ha salido mal, pero usted no sabe la extensión del daño. Abortar temprano.

+3

Cambiaría el parámetro de lista Iterable a Iterable iterable, ya que no todos los iterables son una lista. – Lombo

+0

@limbo: Sí, buena llamada. –

+0

Tenga cuidado al usar este método: debido al uso de la clase Colecciones, el uso de este método implica su lista de ser inmutable – Tanorix

6

Si se van a que List de una llamada a un método que implemente, entonces no vuelven null, regresar un vacío List.

Si no puede cambiar la implementación, entonces está atascado con el cheque null. Si no debe ser null, eche una excepción.

No iría por el método de ayuda que devuelve una lista vacía porque puede ser útil algunas veces, pero luego se acostumbraría a llamarlo en cada ciclo que haga posiblemente ocultando algunos errores.

1

Otra forma de evitar efectivamente un nulo en un bucle for es envolver su colección con Google Guava Optional<T> ya que esto, uno espera, hace que la posibilidad de una recolección efectivamente vacía sea clara ya que el cliente debería verificar si el la colección está presente con Optional.isPresent().

3

he modificado la respuesta anterior, por lo que no es necesario para echar del objeto

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

y luego simplemente llamar a la Lista de

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

Explicación: MyOwnObject: Si List<Integer> entonces MyOwnObject será Integer en este caso.

-2
for (Object object : someList) { 

    // do whatever 
} throws the null pointer exception. 
+6

¿Alguna explicación sobre el código? – Ian

5

TL; DR Uso ArrayUtils.nullToEmpty de la biblioteca commons-lang para Arrays

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

Esta funcionalidad existe en la biblioteca commons-lang, que se incluye en la mayoría de los proyectos de 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; 
} 

Esto es lo mismo que la respuesta dada por @OscarRyz, pero en aras de la DRY mantra, yo creo que es digno de mención. Consulte la página del proyecto commons-lang. Aquí está la entrada Maven nullToEmpty API documentation y source

incluir commons-lang en su proyecto si no lo está ya.

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

Desafortunadamente, commons-lang no proporciona esta funcionalidad para List tipos. En este caso, debería usar un método auxiliar como se mencionó anteriormente.

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

Para cualquier persona interesada en escribir su propio método de seguridad nula estática que puede utilizar: commons-lang de org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object). Por ejemplo:

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

ObjectUtils.defaultIfNull JavaDoc

+0

Para mí, esta respuesta es la más elegante –

18

Es ya el año 2017, y ahora se puede utilizar Apache Commons Collections4

El uso:

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

puede hacer lo mismo cheque nulo segura a otras clases de Colección con CollectionUtils.emptyIfNull.

+2

Aunque funcionará crea un objeto de lista innecesario. Un CollectionUtils.ifNotEmpty puede ser más prolijo pero más eficiente y más rápido. No es que importe mucho ... – Lawrence

+2

En 2017 esperaría List.emptyIfNull (list1) – Dima

+1

@Lawrence, el método no crea nuevos objetos de lista, usa 'Collections.emptyList()' internamente, que a su vez siempre devuelve la misma lista vacía previamente asignada no modificable. –

3

Con Java 8 Optional:

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

Es un operador ternario más detallado que simple como 'someList! = Null? someList: Collections.emptyList() 'y también crea y descarta inmediatamente una instancia del objeto' Optional'. –

0

Uso, CollectionUtils.isEmpty(Collection coll) método que es cheque Null-seguro si la colección especificada está vacía.

para este import org.apache.commons.collections.CollectionUtils.

Maven dependencia

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