2010-06-23 14 views
17

amo Google Guava e lo uso molto, ma c'è un metodo che ho sempre trovato me scrivere ..Perché Iterables.find() in Guava genera NoSuchElementException, invece di restituire null?

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

A me questo sembra essere un accessorio molto utile per Iterables (anche per Iterators per quella materia), quindi mi chiedo perché manchi. Inoltre, mentre posso vedere il punto di avere un metodo che genera NoSuchElementException, forse per distinguere tra ricerca di un nullo e non trovare l'elemento, questa situazione viene solo su se il predicato si sta utilizzando è

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

che doesn sembra essere un caso comune.

Quindi, perché i progettisti guava hanno scelto di avere questo comportamento, invece di restituire null se non riesce a trovarlo?

Ecco javadoc per [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

Forse sarebbe stato meglio lanciare un'eccezione controllata per impedire ai client di dimenticarlo ... – thSoft

+0

Eventuali duplicati di [Iterables.find e Iterators.find - invece di gettare eccezione, ottenere null] (https: //stackoverflow.com/questions/2543052/iterables-find-and-iterators-find-instead-of-throwing-exception-get-null) – Stewart

risposta

32

Stiamo aggiungendo un altro overload di find() che accetta un valore predefinito.

+4

Grazie per l'ottimo lavoro, Kevin! –

+6

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

+1

Che dire di un Optional tryFind (Iterable iterable, int position)? A volte non ho un valore predefinito disponibile e vorrei comunicare che il chiamante della mia API ha bisogno di gestirlo. – jontejj

13

probabilmente perché nullo è un ritorno valido valore. In generale, a meno che non vi sia una buona ragione per non supportare null, dovrebbe essere supportato. Se è supportato, devi gestire il caso in cui esiste.

+1

La necessità di un'operazione find() che restituisce null è altamente discutibile. Sicuramente se tu sai che se c'è un null nella collezione, otterrai nullo di nuovo, quindi potresti usare semplicemente contiene, o qualche altro metodo più semplice esistente. – Trejkaz

4

Invece di tryFind() è possibile utilizzare il filtro e verificare se restituisce una raccolta vuota.

Ho scoperto che lavorare sempre con le raccolte è più semplice che chiedere direttamente gli oggetti.

+0

Hm, ma poi starai iterando due volte, giusto? Vedo che è più pulito, ma .. –

+1

In molti casi il controllo non è più necessario e puoi immediatamente ripetere i risultati. Non succederà nulla quando non ci sono risultati, che nella mia esperienza è spesso il comportamento desiderato. –

3

A mio parere, NoSuchElementException è meglio di un ritardo e molto difficile da eseguire il debug NPE ... Nella maggior parte dei casi, quando si cerca un oggetto in una "raccolta", si sa che probabilmente lo si troverà. Se l'oggetto che stai cercando non è nella "collezione", stai affrontando un caso eccezionale ... Secondo me, il feedback NoSuchElementException è più esplicito del "null" senza significato.

Il valore predefinito che verrà introdotto in una versione futura di guava sarebbe un collegamento efficiente per trattare il caso eccezionale.

0

Trovare avrebbe senso se non fosse possibile trovare piuttosto il valore predefinito.

Optional<T> Iterables.find(Iterable<T>, Predicate<? super T>) 
Problemi correlati