2010-06-23 13 views
17

Me encanta Google guayaba y lo uso mucho, pero hay un método siempre me encuentro escribiendo ..¿Por qué Iterables.find() en Guava lanza NoSuchElementException, en lugar de devolver nulo?

public static <T> T tryFind(Iterable<T> iterable, Predicate<T> predicate){ 
    for(T t : iterable){ 
     if(predicate.apply(t)){ 
       return t; 
     } 
    } 
    return null; 
    } 

Para mí esto parece ser una adición muy útil para Iterables (también a Iterators para el caso), así que me pregunto por qué falta. Asimismo, si bien puedo ver el punto de tener un método que lanza NoSuchElementException, quizás para distinguir entre encontrar un nulo y no encontrar el elemento, esa situación sólo viene para arriba si el predicado que está utilizando es

public boolean apply(T t){ 
    return t==null; 
} 

la que doesn Parece ser un caso común.

Entonces, ¿por qué los diseñadores de guayaba eligieron tener este comportamiento, en lugar de simplemente devolver nulo si no puede encontrarlo?

Aquí es el Javadoc para [Iterables.find()] [1]

[1]: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#find(java.lang.Iterable, com.google.common.base.Predicate)

+0

quizás hubiera sido mejor para lanzar una excepción comprobada para evitar que los clientes olvidarlo ... – thSoft

+0

duplicado posible de [Iterables.find y Iterators.find - en lugar de lanzar una excepción, obtener null] (https: //stackoverflow.com/questions/2543052/iterables-find-and-iterators-find-instead-of-throwing-exception-get-null) – Stewart

Respuesta

32

Estamos agregando otra sobrecarga de find() que acepta un valor predeterminado.

+4

¡Gracias por el gran trabajo, Kevin! –

+6

'Iterables.find (iterable, predicate, defaultValue) ':) –

+1

¿Qué tal un Opcional tryFind (Iterable iterable, int position)? A veces no tengo un valor predeterminado disponible y me gustaría comunicar que la persona que llama de mi API necesita manejarlo. – jontejj

13

probablemente porque nula es un retorno válido valor. En términos generales, a menos que haya una buena razón para no admitir el valor nulo, debería ser compatible. Si es compatible, entonces debe manejar el caso donde existe.

+1

La necesidad de una operación find() que devuelve null es muy cuestionable. Seguramente si sabes que si hay un nulo en la colección, recibirás nulo de vuelta, por lo que también podrías usar el método contains, o algún otro método existente más simple. – Trejkaz

4

En lugar de tryFind() puede utilizar el filtro y comprobar si devuelve una colección vacía.

Encontré que trabajar siempre con colecciones es más limpio que preguntar objetos directamente.

+0

Hm, pero luego estarás iterando dos veces, ¿verdad? Puedo ver que es más limpio, pero ... –

+1

En muchos casos, la verificación ya no es necesaria y puede iterar de inmediato sobre los resultados. Nada sucederá cuando no haya resultados, lo que en mi experiencia a menudo es el comportamiento deseado. –

3

En mi opinión, la NoSuchElementException es mejor que una NPE tardía y muy difícil de depurar ... En la mayoría de los casos, cuando busca un objeto en una "colección", sabe que probablemente lo encuentre. Si el objeto que está buscando no está en la "colección", se enfrenta a un caso excepcional ... Según mi opinión, la opinión de NoSuchElementException es más explícita que la "nula" sin sentido.

El valor predeterminado que se introducirá en una futura versión de guayaba sería un atajo eficiente para tratar el caso excepcional.

0

Encontrar tendría sentido si no puede encontrarlo en lugar de encontrar el valor predeterminado.

Optional<T> Iterables.find(Iterable<T>, Predicate<? super T>) 
Cuestiones relacionadas