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
/ Map
jest 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), Stream
czy też powinienem powrócić do leniwych, ale nie usprawnionych (zgaduję, że tak jest), interfejsów API Guava?
Edytować:
Moim głównym zmartwieniem Stream
jest 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, Collection
a następnie cofnięcia stream()
go (i zapłacenia w tym momencie kosztów niecierpliwości).
Odpowiedzi:
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.
źródło