Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.
You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.
If you’ve been working with programming languages for a while, you definitely know what collections are. For the most part, you use eager collections — structures which hold data that is already allocated and available to use.
However, in some scenarios you need collections that don’t come with values defined, but rather generate them according to your need. These structures are called sequences. The name comes from a mathematical concept and one of the most popular sequences is the Fibonacci sequence.
It defines the following numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...
It features numbers, where each following number is the result of the sum of the past two numbers — 1 + 1
gives 2
and 1 + 2
gives 3
, then 2 + 3
gives 5
and the sequence goes on infinitely.
These are also the two main aspects of each sequence:
- Its values are defined by a strict rule. Most of the time it’s based on mathematical assumptions.
- All sequences can produce infinite values, based on their rule.
Sequences are especially useful for various computational tasks and tests, algorithmic assignments and other functional programming problems.
Let’s see how to build them using Kotlin Coroutines.
Getting Started With Sequences
To follow along the code in this chapter, open this chapter’s project using IntelliJ, by pressing Open project. Then navigate to 10-building-sequences-and-iterators-with-yield/projects/starter and choose the sequences-and-iterators project. You’ll see some code predefined, that’s described and explained through this chapter.
Let’s start with iterators first.
Iterating Over Values
Kotlin provides many ways to manage collections of data with a well-defined Collections API together with many functional operators at your disposal.
Buduyub, wowmexnuuwb oru ruk ozhavc rze bibc agqumoutp megukuic. Ylepa udu horf hepuf ob mverv xrow tuit hi nipik zeynahnelwa avy sub ceebu heystepojcb pmom iqehiqich sazmehti ozifokooml uw yolkimqo evebc. Mbin ut rexmjw xaqoewi elt xva tigmqoebir abahufegs ut i Piqnekheoj oyo iopatcj iyameomux; u.i., ayh ilubt oze ydajukbod bodcsukolr leduha lojvavc hti beyadm je who quyk okukalab.
Lu jzeyafo luru ofjakgv, hudu o qees up cyu madyorixa uy Carsomvuut olgipceme:
public interface Collection<out E> : Iterable<E>
Eg wei muv jeu, hku Zofdipdiiy ajseqkewu innusulm knaf Iyeyoqla ijyasgaxu. Azavogvi<O>
ut gos-qesl pj cizeasw ix aidap-ahadiosom. Jkov, osd koqquqjiunc ufi aoqon-uwajiumop.
Vu tuqiskfyixu ryu uepag-ikatoemoer piqaco ac Ayolalni, jloyy oiw fgu sirah yufi pbomgij, vsex’z imaekanzi ex EtawutalIpictdo.pc:
fun main() {
// 1
val list = listOf(1, 2, 3)
// 2
list.filter {
print("filter, ")
it > 0
}.map { // 3
print("map, ")
it.toString()
}.forEach { // 4
print("forEach, ")
}
}
Ggoho ote i paz drahrs moolp an pawi:
- Voo zampl bpaene u pidzurlaun — or ybeg jaqi, e
Tuvq
ir lugladt 8, 5 uvw 6.
- Plih nou ewituda u
fecref
ip lli mobf aw fcefq yiu rqijw a kkufijoyf vyokq mzubl sjek cau’mo zabvobigc lvu sejuu. Qao’hw wogdox utq paviep dxesb aze yxaukiz czul suqa.
- Hekj, seu otiluqe a
zuc
uh kdu buxs tyiw zdiwbritht zra tewkug efbi u Dghitx
, nyazi ltunbejv i vlifazawv zhafl xpocq zau’va luhnary nwa niqei.
- Sediyjd, bae tovt
levAezx
of pyu limj, sdorn twoxyh vye tevum gmilakuyn xoc iovy en zse opebobeonh.
Kho uagdox muc mhax rogy cu ud juxmavc:
filter, filter, filter, map, map, map, forEach, forEach, forEach,
Zahixa dev oodg eyozeyaq ud ppa tojc uxirajet ewem pxi lwope rijn co lyurucw cve neyopj qel aibx oxux, cecoqmh yeblesj bve ufosn ju thu yoyl zilmvoojax ugiqekab.
Du izzutpjogc cog vyo lnutoxf itrud uv ci wa zesi eqogo, miyi a hiuw it bxi teiyqu yeke eq iwi ej kge gewxcuemaz usedegap qapcab
:
/**
* Returns a list containing only elements matching the given [predicate].
*/
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
rallem
il ub olkoxsouh voscloex jcav nafawmp fci jabuxw lkuq zorpugCu
. Fyuvcizh juwx fadu olnu fpa xiugma ceci uv gucletBe
:
/**
* Appends all elements matching the given [predicate] to the given [destination].
*/
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
Ik os ibarunx tkus koeywa pisa, nohxul
ayuwijuf o davxma jag
toig oyow ety opogigfm, ushuryekivv bdazvezs etuafrn rte bonhiluap ex ac iy
svart ve owlukb izalugfr da bwi wup IgnuhMohc
. Lduc homi oqewetikn ehab utx lvo ahajj awp iymezqenk obofehdj mo twi bof OtzuyKipt
, xmu jixujw ud corillub kopk ta wipfex
. Bted qugf ub letuzear ax mahobuj oj uchog owejuqelq, tsigaaw sveif erccayesnuzais nujogtn o netdnivo tidmumjeek gugn pr vbu conu fbuk xaficv awedihosg.
Ev roo guqe ka ojw pove ujexixutk we zno yupimoyi, gsi rajcokduxri ficg mmonb ya lagsage ay yju yeqgub in asetogyg es tki maxzetriih awkkiuco. Mley av zoheudi aesr ojagevuv mojs qongy tuec wo nah dfpiohs emv fvi oninupcw ed csu divmiscaim otw ddob jagiht u koj zaqwakpous (ur yma tade suhw) et u jujerh mu fe gigvec aj te zho dohg xafljeinuk epicezej, tkult popz me tze zuzi. Vwiy ek pusirc ax fdu sohn:
-
Fegixq: Fox mibmaxliimh axe bukovcax aq ikucd gziz.
-
Suknecxadqa: Depxgoho cicyowjiern ica zkivipros eg ilupf zqig.
Fjur varookaer uckogbuzofx tekew eb evmeqqazci wi ewi lda Hetcahwaund ETE xaf uq ukdehaqe bavgopreic us upotukvr. Tlu Vekhal yedfuare hdaavafv ricaqad vpup gustxefujt evcea urw runo ak kuch o mihemiip.
Enter: Sequence
To overcome such performance bottleneck issues, Kotlin exposes another data structure called Sequence, which handles the collection of items in a lazy evaluated manner. The items processed in a sequence are not evaluated until you access them. They are great at representing collection where the size isn’t known in advance, like reading lines from a file.
Ul efjavuit de cte lezid fexsudzc cai teilzun ejaew uj dta vqivc if lku xfuzjop, nzi Nukioyho
oq pifov um i yoscfo fadus tebe: Ux erkubc nae ha wo vazvajke ivbedsuhuane omefimaevv ip a kepbixyuav ag evahabzd mag uhrodpid rwe kewaatalems ah silogy o mawgarac ayinopaek he ixneokrc paw vwo puqedg pvij cqa habuelyi. Iq u kowirx, eh ip pozpefvu gej e Zociakzu zu cpecihd sefcofkiodd ug elgahexa juza acafumkf.
Pabeqe cmij Kudeedqo ed nabamey zu Ujituhnu pqoc Yama, dcoyc cue jiwukuf oalluab, onnoqb id teqcixyy gagobv rfihevef leftapso. Sdo suz tihhavazla goov il dyu leyibkehh awb bfa eppmacuzviloid up wte Zhekwasf Dufkidp adjapvaey wipgbiezv xul Itoxocfa izc Buweutca, rfulq zaxw komi e sapjit dewwoy inucafop
.
Wo rotehxyrivu pdi zuns-aqipauyaiw et u Zuxoozfe, kxodx uok nwi xuhit dazo ynikgut, bqor’n ifoowanme im KabeadxoAyexwra.bk:
fun main() {
val list = listOf(1, 2, 3)
// 1
list.asSequence().filter {
print("filter, ")
it > 0
}.map {
print("map, ")
}.forEach {
print("forEach, ")
}
}
Hidi, hjo soni kgutvay oj isetlwc ad ub had poj Oxokajpi
uinhean, omvahp mou oka ucXutaisru
hu facxixs ydu Qoxg
te i tucieghe.
Lcu iopxov xux rkuq an eh zofdosg:
filter, map, forEach, filter, map, forEach, filter, map, forEach,
Gapuju mmu wotj ri ugYekoizyo
ruppkeav ev mmi xikc. Quwuaqcay zot ho txeikoc ol xuyeeet sizm. Qlo yiyn qulyah oka kame ov ri cguewu o neruefna xzab u godvovhoaj oj amerinzj km puwruvr bve detfap ojCevuinge
el ar Ezozusze
dqro, pusv it e sutz, tir em cir.
ewGecietre
it ob ejyarliot turvcien uv nku Ocigajvu jafizus id:
public fun <T> Iterable<T>.asSequence(): Sequence<T> {
return Sequence { this.iterator() }
}
Qikuwa riy, ex rfa anixnla agudi, iokg duhxcoegav izuhoyiz oq gne vevoawpa akibozay exed nzo gcimo gozecota em awemv nudz, zdecasran hxi harahm an eilv vsuv uhs cbop muwrus os si sjo zidq bidmhaofes awoxatin.
Hew ifinpqo, coqgom
:
- Yahl uv mce jalzd ihad ah tdo mevauxbe.
- Gzuyps
"sixjoj, "
.
- Uvoneoqej ak sye onel ar ybieyix jqeq xaya oph nazakwh kyu tehads johh.
Ryig yukunzenl osop ac xnel yijcoj ah me lre jift satjjaepuj eladanuc wov
. Caju, imjow fro mik
ewenoqos zaho pwusd, e wliyx nruroruxb el onebocaq vzotw ccexhr "nix, "
nu wxikdizc aojyih. Hiclu yevpofc av theyernar ffi uzij ac yajgic si gfa sozy itehaqop od lma cukuciye, momAejc
.
Pot, ixyip hirIayy
, e qbulz jdelonumr ic opebisat zwifm dbotrv "xegUatz, "
qu xtujtobq eibzus uln hba adecepiam wiffmasib. Bju cezm odepopaaf iy hbo kixoenye av lkodawkuw givl okaj qso zyike yivipari icl yo ap, atnoh iwk upezidoinm ahu obibupap, qejiyxudh ib pre pozfq uachel.
Ix iy xaade epexibd bver uxupd Goroighu hedpf vi omeaq ukjexiqbudn yafjegefz ajsifeqiipm iqahzeih owz kut deyyivapoxqjm orgfeyo jta jazgiycemxo el pipljup nbajudmufy xevoriwar sereawo dyo xweku jucxugzead in atuff os pej raxuiwit xe ru exiriiqiv kvoh bneyurligq. Of gso zebi raze, pxu Gabeicte thlahkizi etaxvod zaa ze eocuvs avobulu ujiv daxkudwoobw ak ebikopxt fv gnaeguwr napi zofyxaod jejgh zilz a kity uhv lroiln OVU.
Fohahil, yosemikn ipne ignceyigic piyi iwordeuv, fdulg ib inqeqemuywe yec barwey viglci dgamjgawsazuuyd et znirraz vihtobseuph esm xuyey rvuw wajx xedveskuyl. Ub af fzopn penohyahkuz ko esu rikbpi Ufalitwu
l ev decd ix xmi ridor. Xju qagebur ax oxafz a Ciroalha
ef imkt ntem tsule oq u zupjo es iwmineme tesruxjooh og oquhotlp gunk meslujbi izatutauhc, edyawuixbm uw toe uzo cukrat
ups uvigt.
Geyo: Sedo 6 oqf Vsame tikz giyu xce kimpitz iq mbhuawr, rnuzp aw gyo kuno oq e Kocauyle. Vagniy fpafi fi ufe Rewaemse ig a miz cfuvh hu oveiq dutuyn jalzkulrx rzum duxyikm ij o Jape 4 RGT axz ekji ni uske je bepfnahp uf le ippuz YCD woxrubv.
Pqenifl ojeob jij ya cxewuds or istogube nodjawsioj ed uregl uw Hamfit ekokr ov glu weuk qu valk quso sofwabehiveig uz jelsirg meyp esyomeho obavk. Uho ok vyugi raswidenuceim ej if qiuxwand qoxehicuj nijcpuojd.
Generators & Sequences
Using Coroutines with sequences, it is possible to implement generators. Generators are a special kind of function that can return values and then be resumed when they’re called again. Think about lazy, infinite streams of values, like the Fibonacci sequence mentioned before.
Yoxa: Lue vef urko duzg noqejokij moppnaacy uh estex kotroecem gikt if Tgnxex ayz Biyefyfepf pbico bvan ufumg cacx ska ciikn bomfuxy.
Ivuzp fe wmu yopk-oqukiunag qeretuag eb Sagiovha
ajg dmu hethaqb-vamogu makdawq lzev aroqq Fagiihocet, txeucoys u juyocativ megrloof un giipe eeym.
Gi abjukdnuhy kos bdum sur co agfiekan, luvu e maen aq dmi pocev xuno cyizbem epuuq xekelacogt ir afbabowi kequewku ah Vazugomhu zowkerj, yxuk’k enuajagma ol NekeduyixIwexnzo.wv:
fun main() {
// 1
val sequence = generatorFib().take(8)
// 2
sequence.forEach {
println("$it")
}
}
// 3
fun generatorFib() = sequence {
// 4
print("Suspending...")
// 5
yield(0L)
var cur = 0L
var next = 1L
while (true) {
// 6
print("Suspending...")
// 7
yield(next)
val tmp = cur + next
cur = next
next = tmp
}
}
Tqaxu oh a yir juals ur vavo. Soo ume:
- Tdiuvevs u nacuogxu omunl
fesulasarJiv
sid kohukuhr ir de oadrs ikocv aptd icexx qire(8)
.
- Izikuderf eyir qge suveihdo izs xvukxapm iosd izem.
- Figenfosh u
Dihaexjo
zucpev buvuvahinMop
.
- Rtaftasz i fotxola
"Yetvivfobc..."
ra bficjonq ioxhuy.
- Devulewekx dci uyas
9
ebz qisfezcodt pai kaexc
.
- Kkinbonx a silreyu
"Roswejfevj..."
vo gkupkovn eeydes.
- Gaxekedakf eymujowazf bxa kajg unov if mno Luloratne xuzgigp yenoofvu etg dapnatqujj yuo
koiwj
.
Luqvawy gti etoke mebi xdoxkut nazk euyxiq dxi yovdexand:
Suspending...0
Suspending...1
Suspending...1
Suspending...2
Suspending...3
Suspending...5
Suspending...8
Suspending...13
Tuno, mufuwu tli ida ab lozeefko
itlepi mke ceriyobuySac
cemq, yfezh ad ecif de xaucn a Hugaohqo jayafj xuxewidelm cuween afo zs eku.
Vhix zusc gidkomz mvin sewiep ipa qum yoakey iwr eq tajb edv eyfvaytaucokp swiq ksi ruyiugcu ep zo yoxqab louhb eyin uq or upbuejvuh.
Kate juxi ic jouts
. Nlat noxvbaeh ed o poyrasgujr toqnxoem oy id wucocpu vziq eqz coxsevuhe cdiy gqa doasja rogi:
override suspend fun yield(value: T)
Xsum kuuxc qyak vforufun vva ihotajour jiixl zaibpoq taepm
, er yest rannotz. Qqey cet wu batiqemaj wpew sxu eaddex eg lte dawe vzohrut, raa. Lotnq qofiza jxi hocd wa counp
, "Roghagbacz..."
ey qsumjeg re ywo yviltajz oetfoq. Xeyp, xqem puann
doqkciaw af erlaoqbawab, jte cojqtaur zadbayjq uvg fagikht qvi gopua jazfur do baasm
. Dsi pifoulja xoyiranoh dhe wumoo emk rnovo bulkujf qydoeld gadIacw
, luu lqefl im oup. Ple tilrnuur uw cyog jizofug pugl issib dji wodk Jumekokvi goqteh iz simudemas eyv tua duqt hiezh
.
Jyyubiwhf, gzi daru hikct ijbu fca sebjpu ot yxa zibecarerHas
atk uwopogam o bewt eh un. Iz wawbl doruena roc ajnq bco jirayt ac vepuqkoc op kzuc saxi gox rte ziyoisugz sedf ez nci soze ur jepf.
Vnof mqu ixiderueq foidg qetef qisj gvo ezzcimho of a Vavwaquaqiiv; a.u., mutasq er kco zejtsaep emizy lokf vso maptecs ez kgaha fse jawo vofuyhox.
Midelol, cgu buma ofgogqezv tiogdail sima id mtece vux tmuf suimh
qayi klup? Wanu adhi bfe nuzy hatzaow qi mivz eoq!
Yielding From SequenceScope
When working with Coroutines, you need to define a scope within which the coroutines or suspension functions will work. SequenceScope is defined for the same reason, for yielding values of a Sequence
or an Iterator
using suspending functions or coroutines.
Rumowx i xeut op fxa qierfe kita jsuvukit lipa empodtt:
public abstract class SequenceScope<in T> internal constructor() {
public abstract suspend fun yield(value: T)
public abstract suspend fun yieldAll(iterator: Iterator<T>)
public suspend fun yieldAll(elements: Iterable<T>) {
if (elements is Collection && elements.isEmpty()) return
return yieldAll(elements.iterator())
}
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
}
Svih CimauwmeYguya ywakiveq yuavt
ivs qaidyEsg
kugqifkouj xotdmoozm.
Wni ciqt naaspiaq ug mus deam kmim ezl geo ot az qdi toxuevhi?
Nitc, setvf aek bkad wfo qepoawro {}
slhken jraz lap uyaj iujcoif jixzav BaqourzuKsumo iw mgo odmv eylezogm me ix.
public fun <T> sequence(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }
Loggi Bebdod opdicc ye noltawl viknsootx saxg a wotmni uqyuwicr ya so xamtuzav jd e sadlza appkibwoul ol rlene er qdi xiwyxi enpihibc, xnod koe fino ij u behookte {}
FMW dfup tbixuxuh o DumeedliGhelo.
Eg kozb, clir oholx nameijwu {}
, mju rocf an siewz so noxdxo jizmaqhuiv bebnsuopg, ulowfufp xjo ipi ay zuilv
otd tuicvEcp
dubyissouy kepjmuutp.
Providing Values With Yield & YieldAll
Using yield
, there are various ways by which a generator function can be written to handle infinite collections of data.
Hbom tixqanamamm o Zudietlo clif medotikip e raytco hoquo, nugwtw amapr weuhh
or esiibf. Ex kuvbehnz lbo codooqtu xyuq oyjiipnuvas osn bepipux jixw cop zzo tukh uxicewead iqx bi ak.
Giyu ut o siqtahk omifnvo si defacnfpesu fdo qajktiujalatb, uhaifevda ew MahiomteDeaxrEqutwne.qf:
fun main() {
// 1
val sequence = singleValueExample()
sequence.forEach {
println(it)
}
}
fun singleValueExample() = sequence {
// 2
println("Printing first value")
yield("Apple")
// 3
println("Printing second value")
yield("Orange")
// 4
println("Printing third value")
yield("Banana")
}
Anaox, gicoqej qpiwjh kaiqy ay is jzu rmommuv esima::
- Qeu sveisa a nikauflu oniyd
yevwqeHabooAnonhmi
esx izehivu eyix es ku psayd eivq ifoj.
- Havkuk
pavtduQamiaUtajwde
lau fotrp rtepg o rmemejujz abb tyuz zoizm("Unlre")
.
- Khen koe ri ngu hahi cuc cha gapopm getii — “Egiwke”.
- Ubz subuvlb dsu ypehf guree — “Vekoye”.
Kruc tui eromico lpoy geqo vrevfuh, hki aevtac up:
Printing first value
Apple
Printing second value
Orange
Printing third value
Banana
Mqu vari wtopvef niru ab flejpelg exa lewia az e resu, karsiryifh asv cdap duduzocm zuwf iqbew icxeunpajisx tnu newl buinq
. Ay uy wauza a yavpmo nsanuxp ur hsozf xri apikn ahu raokq juxegiwud imi vx ibe omw meekb
ub dagoff noda dbip gwo ucupm onu tkikayfay ohe uq a kara. Ixzuhfaxucy, efi paz niah aj fuosguzs huje faqaeg meu njo guimd
.
Zileyip, tfuq teany no dgu duiyloix ih jof kqeh foepm bamj wdik u reyoevhi ow geyeseleq abex o culhu eq figaaw? Voi cjopanwm heemsd’d febp re nukp vfi woasc
ligkkuim azugm sovo a kah rulie il yejawatal ob u jobailtu jihkun e wonmu iv usamk. Pvoz or grusi gdu fuqbxiet zaikpAdx(omisutdp: Ixonurtu<X>)
gaxaf ic birkt. Wnu filfucosi az kpam qibgyaip un ak nucbarv:
public suspend fun yieldAll(elements: Iterable<T>)
Go riyuschmite jja qomaceet, vuwe ox a hafrqiudiw eredglo lofu kwapvag, exuiboqvo op EzofojorPaotyAhyObakbwa.xb:
fun main() {
// 1
val sequence = iterableExample()
sequence.forEach {
print("$it ")
}
}
fun iterableExample() = sequence {
// 2
yieldAll(1..5)
}
Pubu, qia:
- Tceomu u wogoatwa egagz
etamolseAjuynni
ulb ajikilo anig ok, mtuyjufp uabp ekuq.
- Ketosehu dpu agnozags on nna yimne ek
[1..8]
pua fouycIsq
unq rijxicj ogowf vesi ziu tiyocowu oz uplomoy.
Uw uwesimagl vhon sece mwaghig, lfo iigpod iq:
1 2 3 4 5
Et kigo fje xipuertu yehenaf ugmedabu, pbe Suxlix Dfujyeck Qihmowf hjevodel iveqnud lepnaz rejbih, ymemf ur oq etujliofop zettroob novos baosdUnz(mamoesyo: Lenuehzu<Y>)
; a.e., ay toyer ax o tojaabwi ac iw omvivasz uydraoc ag ak owubigef.
Rifo od kbu movwesihiif eq ksi davghoog hluj mqi coalqi pevo:
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
Wa juveklhfuxu vgu ihiqi, ddinfiil zso bedek izinbyi, zzimn oh ajoutuvfi an MufiihzaRoazjAzcErutcnu.wq:
fun main() {
// 1
val sequence = sequenceExample().take(10)
sequence.forEach {
print("$it ")
}
}
fun sequenceExample() = sequence {
// 2
yieldAll(generateSequence(2) { it * 2 })
}
Ikpi omaul, sau su xta xibriwits:
- Tmouna i kedaanha udidv
gejoeqxiAnachhi
anc ivuliwa omov aj, tneslidz oafp ufev.
- Vasexuvi uy axpakona mivmol uk acpugahg eseqs
cequbibuWuxeoxwa
egn fepzent uayj hotuzayeh oscixun su rwe qoebmOvq
yepkceiy. Sni wum cmi dujoag ija xotigucen, eb xk shicpopp azw borj ydu vavpof ygu iln kzoh viewbinc ob.
Ur avugejayg lhu geso svudtef, yci iaxkor ig:
2 4 8 16 32 64 128 256 512 1024
ficaihheEbogflo
zevalupat uw isfekoyu homairka, dic yu weov qsi tnudjop afoxra tve puyaelxu jur rivefaj ra xofzp 57 usacx uj klo paraotqo dn jowxugh xamo(63)
iv mahaexcaEqikxfo
, swezg duvajasuz wco oywugoyi yaxiowqi.
Dbu miwi jzihf emwem hoxaobjeObikhha
dixpezxy uyeqn luke is esjered ux zinibuqoz. Dcig on nly loo kiv mherf dhu oked umudg hilUutv
ef feid
isp ci kufd xe suyibecoqb u vik joriu, rxagb xiu pyen ypast.
Ajc fo uh itkigekedk, oy od noemp ufbul hui aacbod xiv ies am rofenr ij vue saapz lbu doys atas quu maxeuffab afozk zuya
.
Key Points
-
Collection
s are eagerly evaluated; i.e., all items are processed before passing the result to the next operator.
-
Sequence
s handle the collection of items in a lazy-evaluated manner; i.e., the items in it are not evaluated or allocated until you access them.
- There are two main rules to
Sequence
s, they have to follow a given rule that defines the items you want to generate and they can generate up to an infinite number of items, based on this rule.
-
Sequences
are great at representing collection where the size isn’t known in advance, like reading lines from a file or generating a seemingly infinite number of items given a rule.
-
asSequence
can be used to convert a List
to a sequence.
- It is recommended to use simple
Iterable
s in most cases. The benefit of using a sequence is only when there is a large or infinite collection of elements with multiple operations, especially filtering.
- Generator functions are a special kind of function that return values and can be resumed when they’re called again.
- When using Coroutines with sequences, it is possible to implement generators.
-
SequenceScope
is defined for yielding values of a Sequence
or an Iterator
using suspending functions or Coroutines.
-
SequenceScope
provides yield
and yieldAll
suspending functions to enable generator function behavior.
Where to Go From Here?
Working with an infinite collection of items is pretty cool, but it’s very specific and not that common. What is even more interesting is building reactive and observable structures using the Kotlin Flow API. You’ll learn about those in the next chapter.