Java 8: Dobra praktyka przekazywania strumieni w interfejsach API dla opóźnionych operacji?

12

W bibliotekach ciężkich przed biblioteką Java 8, takich jak Guava, dane wyjściowe używają wspólnych interfejsów Java Collection Framework, więc łatwo jest przekazać je zewnętrznym / wewnętrznym interfejsom API i nadal wykorzystywać leniwe obliczenia, jeśli metoda biblioteczna to robi (np. Leniwa filter()i transform()).

Jednak w strumieniach Java 8 wezwanie do uzyskania Collection/ Mapjest terminalem (tzn. Chętnym), a także przydzieli nowe struktury danych do przechowywania wyników.

W przypadku skomplikowanych obliczeń z wieloma etapami i wzorcem strategii pośrodku powoduje to wiele niepotrzebnych alokacji z powodu wyników pośrednich.

Czy ludzie uważają więc, że dobrą praktyką jest przyjmowanie i zwracanie wewnętrznych interfejsów API (tj. Strategii wzorców strategii), Streamczy też powinienem powrócić do leniwych, ale nie usprawnionych (zgaduję, że tak jest), interfejsów API Guava?

Edytować:

Moim głównym zmartwieniem Streamjest to, że można go spożywać tylko raz, a przekazywanie czegoś takiego Supplier<Stream<X>>wygląda na wyjątkowo niewygodne. Prawie popycha cię to tylko do zaliczenia, Collectiona następnie cofnięcia stream()go (i zapłacenia w tym momencie kosztów niecierpliwości).

billc.cn
źródło
Co, Guava i przyjaciele nie są aktualizowane, aby korzystać z rodzimych strumieni?
Kilian Foth,
1
Posiadanie interfejsów odbierających i zwracających strumienie naprawdę poprawia interoperacyjność ze standardowymi funkcjami strumienia. Pozwala zintegrować połączenia z interfejsem z potokiem strumienia.
Philipp
@KilianFoth Od prawie roku nie było żadnego wydania Guava i istnieje wiele popularnych artykułów na temat zastąpienia materiałów lambda Guava Streamem; jednak żadna z nich nie odnosi się do faktu, że operacje zbierania Guawy mogą być chętne lub leniwe.
billc.cn

Odpowiedzi:

3

Lenistwo w strumieniach Java 8 działa tak samo jak w przypadku Iterables w Guava: musisz przekazać Iterable, aby pozostać leniwym i odbywa się ocena, gdy zbudujesz kolekcję z Iteratora. Zarówno strumienie, jak i iteratory można wykorzystać tylko raz.

Tak więc w przypadku interfejsów metod bardziej ogólnym sposobem (pozwalającym na lenistwo) jest użycie interfejsu Stream (za każdym razem, gdy wcześniej używałeś Iterable). Jak mówi @Philipp, pozwala to na ich użycie w potokach Stream.

Mamy nadzieję, że skoro Stream jest teraz oficjalnym standardowym interfejsem Java, będzie coraz więcej innych bibliotek i funkcji, które mogą efektywnie działać bezpośrednio na strumieniach.

Robert Jack Will
źródło