2010-06-23 16 views
17

Kocham Google Guava i używać go dużo, ale jest jedna metoda zawsze znajdę mi pisanie ..Dlaczego funkcja Iterables.find() w Guava generuje wyjątek NoSuchElementException, zamiast zwracać wartość zerową?

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

Dla mnie to wydaje się być bardzo użytecznym dodatkiem do Iterables (również do Iterators dla tej sprawy), więc zastanawiam się, dlaczego go brakuje. Ponadto, podczas gdy widzę sens posiadania metodę, która rzuca NoSuchElementException, może odróżnić znalezienie nieważne i nie znalezienie elementu, że sytuacja przychodzi tylko wtedy, gdy orzeczenie używasz jest

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

który robi wydaje się być powszechnym przypadkiem.

Dlaczego projektanci guava zdecydowali się na takie zachowanie, zamiast zwracać wartość zerową, jeśli nie mogą jej znaleźć?

Oto javadoc dla [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

Może byłoby lepiej, aby rzucić wyjątek sprawdzane, aby zapobiec jej klientów od zapomnienia ... – thSoft

+0

Możliwa duplikat [Iterables.find i Iterators.find - zamiast rzucać wyjątek uzyskać null] (https: //stackoverflow.com/questions/2543052/iterables-find-and-iterators-find-instead-of-throwing-exception-get-null) – Stewart

Odpowiedz

32

Dodajemy kolejne przeciążenie find(), które akceptuje wartość domyślną.

+4

Dzięki za wspaniałą pracę, Kevin! –

+6

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

+1

A co z Opcjonalnym tryFind (Iterable iterowalna, pozycja int)? Czasami nie mam dostępnej wartości domyślnej i chciałbym poinformować, że osoba dzwoniąca z mojego interfejsu API musi się z nią skontaktować. – jontejj

13

prawdopodobnie ponieważ null jest ważny zysk wartość. Ogólnie mówiąc, chyba że istnieje dobry powód, aby nie obsługiwać wartości null, powinno to być obsługiwane. Jeśli jest obsługiwany, musisz zająć się przypadkiem, w którym istnieje.

+1

Potrzeba operacji find(), która zwraca wartość null, jest wysoce wątpliwa. Z pewnością, jeśli wiesz, że jeśli w kolekcji jest w ogóle zerowa, otrzymasz zerową wartość, więc równie dobrze możesz użyć opcji zawiera lub innej prostszej istniejącej metody. – Trejkaz

4

Zamiast funkcji tryFind() można użyć filtru i sprawdzić, czy zwraca pustą kolekcję.

Odkryłem, że praca z kolekcjami zawsze jest czystsza niż bezpośrednie zadawanie obiektów.

+0

Hm, ale potem będziesz powtórzył dwa razy, prawda? Widzę, że jest czystszy, ale .. –

+1

W wielu przypadkach czek nie jest już potrzebny i możesz od razu powtórzyć wyniki. Nic nie stanie się, gdy nie będzie rezultatów, co często jest moim zdaniem pożądanym zachowaniem. –

3

Moim zdaniem, wyjątek NoSuchElementException jest lepszy niż spóźniony i bardzo trudny do debugowania NPE ... W większości przypadków, gdy przeszukujesz obiekt w "kolekcji", wiesz, że prawdopodobnie go znajdziesz. Jeśli szukany obiekt nie znajduje się w "kolekcji", masz do czynienia z wyjątkowym przypadkiem ... Według mnie, informacja zwrotna od NoSuchElementException jest bardziej wyraźna niż bezsensowna "null".

Wartość domyślna, która zostanie wprowadzona w przyszłym wydaniu guawy, byłaby skutecznym skrótem do traktowania wyjątkowego przypadku.

0

Znajdź miałoby sens, gdyby nie mógł znaleźć raczej znalezienie wartości domyślnej.

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