W Kotlinie Sequence to leniwe sekwencje, które pozwalają efektywnie pracować z dużymi lub nawet potencjalnie nieskończonymi zbiorami danych. Operacje na Sequence (np. map, filter) nie są wykonywane natychmiast; zamiast tego budowana jest sekwencja działań, a obliczenia odbywają się tylko w razie potrzeby (przy operacji terminalnej, np. toList).
Dlaczego to ważne:
Przykład kodu:
val numbers = generateSequence(1) { it + 1 } .filter { it % 2 == 0 } .map { it * it } .take(5) .toList() println(numbers) // [4, 16, 36, 64, 100]
W tym przykładzie tylko 5 pierwszych elementów sekwencji zostanie rzeczywiście obliczonych, pomimo że jest ona potencjalnie nieskończona.
Kiedy używać Sequence:
Czy można zagwarantować, że operatory typu
mapifilterw zwykłych kolekcjach Kotlin również są leniwe? Dlaczego?
Odpowiedź: Nie, standardowe operacje kolekcji (List.map, List.filter itd.) w Kotlinie są ściśle zachłanne. Każda operacja tworzy pośrednią kolekcję i natychmiast przetwarza wszystkie elementy. Leniwość wspierana jest tylko przy użyciu Sequence.
Przykład:
val data = listOf(1,2,3,4) val mapped = data.map { println("Mapping $it"); it * 2 } // Natychmiast drukuje wszystkie wartości
Historia
W projekcie przetwarzającym duże pliki CSV (do gigabajta podczas zapisu) kolekcja była najpierw wczytywana w całości do List, po czym stosowano chain map/filter. Aplikacja „siadała” z powodu OutOfMemory — problem rozwiązano, zastępując List na Sequence, której map/filter nie tworzyły ogromnych pośrednich list.
Historia
Backend serwis do agregacji raportów z wielu baz danych najpierw gromadził wyniki wyszukiwania w List i później filtrował: zapytania stały się wolne, występowały lagi GC. Zastąpienie na generator + Sequence pozwoliło agregować dane na bieżąco, zmniejszając opóźnienia wielokrotnie.
Historia
Migrowany z Java projekt używał standardowych rozszerzeń Kotlin (map, filter) bez przejścia na Sequence podczas pracy z dużymi strumieniami danych, zakładając, że kod działa leniwie, jak strumienie Java 8. Błąd prowadził do poważnych wycieków pamięci i nagłych awarii w produkcji.