Jakie są różnice między strumieniami, widokami (SeqView) i iteratorami w scali? To jest moje zrozumienie:
- Wszystkie są leniwymi listami.
- Strumienie buforują wartości.
- Iteratory mogą być użyte tylko raz? Nie możesz wrócić do początku i ponownie oszacować wartości?
- Wartości widoku nie są zapisywane w pamięci podręcznej, ale można je wielokrotnie oceniać?
Jeśli więc chcę zaoszczędzić miejsce na stosie, czy powinienem używać iteratorów (jeśli nie będę ponownie przechodzić przez listę) lub widoków? Dzięki.
Odpowiedzi:
Po pierwsze, wszystkie nie są rygorystyczne . Ma to szczególne znaczenie matematyczne związane z funkcjami, ale zasadniczo oznacza, że są one obliczane na żądanie, a nie z góry.
Stream
to rzeczywiście leniwa lista. W rzeczywistości w Scali aStream
jest,List
któregotail
jestlazy val
. Po obliczeniu wartość pozostaje obliczona i jest ponownie wykorzystywana. Lub, jak mówisz, wartości są buforowane.Można
Iterator
użyć tylko raz, ponieważ jest wskaźnikiem przechodzenia do kolekcji, a nie kolekcją samą w sobie. To, co czyni go wyjątkowym w Scali, to fakt, że możesz zastosować transformację taką jakmap
ifilter
i po prostu uzyskać nową,Iterator
która zastosuje te transformacje tylko wtedy, gdy poprosisz o następny element.Scala dostarczała iteratory, które można zresetować, ale jest to bardzo trudne do utrzymania w sposób ogólny i nie stworzyli wersji 2.8.0.
Widoki mają być przeglądane podobnie jak widok bazy danych. Jest to seria transformacji, którą stosuje się do kolekcji w celu stworzenia kolekcji „wirtualnej”. Jak powiedziałeś, wszystkie transformacje są ponownie stosowane za każdym razem, gdy musisz pobrać z nich elementy.
Zarówno
Iterator
widoki, jak i widoki mają doskonałą charakterystykę pamięci.Stream
jest fajny, ale w Scali jego główną zaletą jest pisanie nieskończonych sekwencji (szczególnie sekwencji definiowanych rekurencyjnie). Można jednak uniknąć przechowywania całego theStream
w pamięci, upewniając się, że nie przechowujesz odniesienia do jegohead
(na przykład używającdef
zamiastval
definiowaniaStream
).Ze względu na kary, jakie ponoszą widoki, zazwyczaj należy to
force
zrobić po zastosowaniu transformacji lub zachować jako widok, jeśli oczekuje się, że tylko kilka elementów zostanie kiedykolwiek pobranych, w porównaniu do całkowitego rozmiaru widoku.źródło
Iterator
jest również bardzo przydatny do badania nieskończoności i generalnie wolę je od strumieni, jeśli to możliwe. Prawdziwą zaletą strumieni jest to, że wcześniej dostępne wartości są buforowane, co jest poważnym dobrodziejstwem, gdy próbuje się zaimplementować coś w rodzaju sekwencji Fibonacciego - która jest zdefiniowana w kategoriach poprzednich wartości.