Scala for Backend Engineering & Functional Programming · Lekcja

Leniwe pobieranie i filtrowanie

Podzieli Pan/Pani nieskończone strumienie na fragmenty.

Lekcja 4 z 413 kroki

Leniwe pobieranie i filtrowanie to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Leniowe pobieranie

Prawdziwa wartość LazyList ujawnia się podczas jego pobierania. Operacje takie jak take, filter i map pozostają leniwe, obliczając tylko te komórki, które ostatecznie wymusisz.

W tej lekcji omówimy najważniejsze transformatory oraz sposób zatrzymywania leniwości we właściwym momencie.

take(n)

take(n) zwraca LazyList zawierający co najwyżej pierwszych n elementów, który sam nadal jest leniwy. Nic nie zostanie obliczone, dopóki nie wymusisz wyniku.

To bezpieczny sposób na ograniczenie nieskończonego strumienia.

object Demo extends App {
  val first5 = LazyList.from(1).take(5)
  println(first5.toList)
}

takeWhile

takeWhile(p) zwraca elementy tak długo, jak predykat jest spełniony, a następnie zatrzymuje się przy pierwszym niespełnieniu.

W przypadku nieskończonego strumienia jest to przejrzysty warunek zakończenia, który nie wymaga znajomości liczby elementów.

object Demo extends App {
  val small = LazyList.from(1).takeWhile(_ < 6)
  println(small.toList)
}

drop i dropWhile

drop(n) pomija pierwszych n elementów, a dropWhile(p) pomija elementy tak długo, jak predykat jest spełniony. Obie metody zwracają leniwą pozostałą część.

Używaj ich do przejścia do wybranego miejsca w strumieniu przed pobraniem fragmentu.

object Demo extends App {
  val rest = LazyList.from(1).drop(3).take(3)
  println(rest.toList)
}

Leniwe filtrowanie

filter na LazyList jest leniwe: testuje elementy dopiero wtedy, gdy pobiera je konsument znajdujący się dalej w potoku.

W połączeniu z take przetwarzasz dokładnie tyle elementów źródłowych, ile potrzeba do zaspokojenia zapotrzebowania — ani jednego więcej.

object Demo extends App {
  val evens = LazyList.from(1).filter(_ % 2 == 0)
  println(evens.take(4).toList)
}

Obserwowanie zapotrzebowania

Dodaj instrukcję print wewnątrz predykatu, aby zobaczyć, jak niewiele elementów zostaje sprawdzonych. Filtrowanie działa tylko do momentu spełnienia warunku take.

Uruchom ten kod: liczba wierszy z napisem "check" pokazuje ewaluację sterowaną zapotrzebowaniem, a nie przetwarzanie całego strumienia.

object Demo extends App {
  val r = LazyList.from(1).filter { n =>
    println("check " + n); n % 3 == 0
  }
  println(r.take(2).toList)
}

Łączenie map i filter

Możesz łączyć transformatory — cały potok pozostaje leniwy i jest łączony dla poszczególnych elementów. Każdy element źródłowy przechodzi przez map, a następnie filter dopiero wtedy, gdy zostanie pobrany.

Nie są tworzone pośrednie pełne kolekcje.

object Demo extends App {
  val r = LazyList.from(1).map(_ * _).filter(_ > 10).take(3)
  println(r.toList)
}

find: wczesne zatrzymanie

find(p) zwraca pierwszy pasujący element jako Option, wymuszając obliczenia tylko do tego elementu. Doskonale nadaje się do przeszukiwania nieskończonego strumienia.

Po znalezieniu dopasowania ewaluacja natychmiast się zatrzymuje.

object Demo extends App {
  val firstBig = LazyList.from(1).find(_ * _ > 50)
  println(firstBig)
}

headOption i exists

headOption bezpiecznie sprawdza pierwszy element, a exists(p) wymusza obliczenia tylko do znalezienia dopasowania (lub trwa bez końca, jeśli go nie ma). Używaj exists na nieskończonych strumieniach tylko wtedy, gdy dopasowanie jest gwarantowane.

Obie metody zatrzymują się tak wcześnie, jak to możliwe.

object Demo extends App {
  val has = LazyList.from(1).exists(_ == 7)
  println(has)
}

Wymuszanie wyniku

Len iwe transformatory opisują pracę, a operacja terminalna ją wymusza. toList, foreach, sum i foldLeft konsumują (ograniczony) strumień i tworzą konkretną wartość.

Zawsze ogranicz nieskończony strumień przed operacją terminalną, która wymaga przetworzenia wszystkich jego elementów.

object Demo extends App {
  val total = LazyList.from(1).take(100).sum
  println(total)
}

Pułapki podczas filtrowania

Element filter, który niczego nie dopasowuje, zamienia ograniczone take w nieskończone wyszukiwanie. LazyList.from(1).filter(_ < 0).take(1) zawiesi się na zawsze.

Upewnij się, że predykaty mogą zostać spełnione, albo połącz filtrowanie z takeWhile, aby zagwarantować zakończenie.

Szybki test

Sprawdź, czy rozumiesz leniwe pobieranie.

Podsumowanie

take, takeWhile, drop, filter i map pozostają leniwe i są łączone dla poszczególnych elementów; find, exists i headOption zatrzymują się wcześnie, a operacje terminalne, takie jak toList i sum, wymuszają wynik.

Chroń się przed filtrami, których nie da się spełnić, na nieskończonych strumieniach. Potrafisz już z przekonaniem generować i konsumować leniwe sekwencje.

Bezpłatny start

Ucz się Scala dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
39
Lekcje
143

Często zadawane pytania

Czy lekcja „Leniwe pobieranie i filtrowanie” jest bezpłatna?

Tak — pełny tekst „Leniwe pobieranie i filtrowanie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Co nauczysz się w „Leniwe pobieranie i filtrowanie”?

Podzieli Pan/Pani nieskończone strumienie na fragmenty. Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?

Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Leniwe pobieranie i filtrowanie”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?

Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wyjaśnienie leniwości
  2. Budowanie LazyList
  3. Nieskończone strumienie
  4. Leniwe pobieranie i filtrowanie
← Powrót do Scala for Backend Engineering & Functional Programming