Kiedy powinienem zaakceptować parametr Iterable vs. Collection w Javie?

Jakie są względy stosowania Iterable<T> vs.Collection<T> w Javie?

Na przykład rozważ implementację typu, który dotyczy przede wszystkim zbioru Foo s i niektórych powiązanych metadanych. Konstruktor tego typu umożliwia jednorazową inicjalizację listy obiektów. (Metadane można ustawić później.) Jaki typ powinien przyjąć ten konstruktor? Iterable<Foo>, czy Collection<Foo>?

Jakie są względy dla tego decyzja?

Przestrzeganie wzorca określonego przez typy bibliotek, takie jak ArrayList (które mogą być inicjowane z dowolnego Collection, ale Nie ani Iterable) doprowadziłoby mnie do użycia Collection<Foo>.

Ale dlaczego nie zaakceptować Iterable<Foo>, biorąc pod uwagę, że jest to wystarczające dla potrzeb inicjalizacji? Po co żądać od konsumenta wyższego poziomu funkcjonalności (Collection) niż to, co jest bezwzględnie konieczne (Iterable)?

Author: Lonely Neuron, 2009-07-21

9 answers

Wiele typów kolekcji istniało przed Iterable<T> (który został wprowadzony dopiero w 1.5) - nie było powodu, aby dodać konstruktor do accept Iterable<T> jak również Collection<T> ale zmiana istniejącego konstruktora byłaby przełomową zmianą.

Osobiście użyłbym Iterable<T> jeśli to pozwala Ci robić wszystko, co chcesz. Jest bardziej elastyczny dla rozmówców, a w szczególności pozwala zrobić stosunkowo łatwe filtrowanie / projekcja / etc przy użyciu Google Java Collections (i bez wątpienia podobne biblioteki).

 57
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 13:41:03

An Iterable produkuje Iterator obiekty. Obiekt Iterator z definicji jest iteracją . Zauważ, że interfejs Iterator nie daje żadnej obietnicy ile razy next() może być wywołany przed hasNext() zwróci false. {[1] } może być iteracją nad wartościami Integer.MAX_VALUE + 1, zanim jej metoda hasNext() zwróci false.

Jednak Collection jest specjalną formą Iterable. Ponieważ Collection nie może mieć więcej niż Integer.MAX_VALUE elementów (na mocy metody size()), naturalnie zakłada się, że jego Iterator obiekty nie będzie iterować nad tak wieloma elementami.

Dlatego akceptując Collection zamiast Iterable, twoja klasa może mieć pewną gwarancję, ile elementów jest przekazywanych. Jest to szczególnie pożądane, jeśli twoja klasa sama w sobie jest Collection.

Tylko moje dwa centy...
 17
Author: Adam Paynter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-21 15:23:03

Użyj najbardziej ogólnego interfejsu, jaki możesz. Ponieważ wszystko, co zamierzasz zrobić, to iterację, to powiedziałbym, że Iterable jest drogą do zrobienia (ponieważ pozwala na leniwe Iteratory itp.). Nie obchodzi cię, skąd pochodzi iterator, więc nie ograniczaj go bardziej niż musisz.

 8
Author: Michael Myers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-21 15:18:26

Użytkownicy Spring Data JPA przekonają się, że Repositories zwracają zbiory typu Iterable<T>.

W projektach, nad którymi pracowałem w przeszłości, używających Spring, odkryłem, że potrzeba operowania na kolekcji po pobraniu często dyktowała, że Iterable<T> jest używana w warstwie biznesowej, a nie Collection<T> w celu wybrania obiektu T z kolekcji.

Wszystkie kolekcje to Iterable (czyli interfejsy rozszerzające interfejs Collection, a nie Map!), więc używanie Iterable w biznesie layer jest tylko przypadkiem odniesienia do zbioru przez jego super typ i nadal pozwala na użycie for-each do iteracji.

Jeśli chcesz manipulować zawartością kolekcji, wygodna metoda pozwoli Ci wypełnić nową Collection, abyś mógł skorzystać z contains(), remove(), itp z oryginalnymi danymi kolekcji.

Alternatywnie, metody wygody są dostarczane w tym celu przez popularne interfejsy API stron trzecich, takie jak Google Guava i Apache Commons.

 7
Author: 8bitjunkie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-03 20:33:11

Niektóre konstruktory, np. ArrayList (Kolekcja c), używają metody zbioru toArray() dla efektywności.

 4
Author: starblue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-21 15:24:17

Zobacz " skąd taki nacisk na Iteratory i iterable?"na Google Collection FAQ za przyzwoity argument za preferowaniem iteratorów, zwłaszcza gdy mamy do czynienia z dużą ilością danych. Jedną z analogii, która może pomóc, jest myślenie o różnicy między kursorami tylko do odczytu do przodu i kursorami przewijalnymi.

 3
Author: Rick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-27 22:21:47

Jeśli wybierzesz Collection, wtedy twoja klasa może być zainicjalizowana tylko z kolekcji, jeśli wybierzesz Iterable, wtedy możesz zainicjalizować ją z kolekcji lub iterable.

Ponieważ wysiłek i wydajność dla obu będzie taka sama, ma sens akceptowanie iterowalnych w konstruktorze.

 2
Author: Patrick McDonald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-21 15:20:20

Zgodnie z zasadą najmniejszego zaskoczenia, należy emulować wzorzec kolekcji Java i wziąć konstruktor kolekcji arg. To sprawi, że ludzie, którzy przyjdą po ciebie nieco mniej zdziwiony.

 0
Author: Paul McKenzie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-30 15:45:50

Masz rację, ponieważ jest to dobra praktyka, aby poprosić o najbardziej ogólną formę tego, czego potrzebujesz.

 -1
Author: Steve B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-21 15:17:36