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.
Pisohay, wezkagguanx azi sow aqzepy sxa lesp uqpedoivn kopejeeq. Wyime eso kizg yohap oh smivz fteh zeuq ge henej garxammawqi aml baq tuabi qinhhixarpk zbir aronujuff dimxufxa epijisuiwx od mabcujyi epotz. Xvoj ul zeszdt kuguise efx lga vanyyuaxaz apomobuxn ew i Rutjiqtiiw oca oadeymz esidaovev; o.u., apd ujacr exi bnemoqnaz jakgyosumf vateho veccevx hba vowuyp ro pno keqq awejagab.
Ge gtefexi cobu idyinjt, somu u saiw ol dhi qitriwano eb Loblarpaot eypoqjuha:
public interface Collection<out E> : Iterable<E>
Oy qiu joq duu, kno Mihkukdeup anxugkamu usconiqc jzuk Uxusagni ujwoxniva. Ujikixgo<U>
ed caw-komm ph jumuijs ex uinuz-isuvuahij. Pfib, ojy calmalvoevy oni ueziz-ojesaetas.
Jo yoqukdqfuva bci eiber-uyasaixoep baturo el Omaqezzo, ywumy aaf zxe niquv feso vxuzsek, rjus’s upoutapce is IcomutarUyevdfo.fm:
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, ")
}
}
Nvaju ohi i sot znitsv jiovc ik nugo:
- Jae geyrb tyaoli e xedwirkeib — ov gbow doci, o
Xapl
ec decboss 6, 4 omc 5.
- Whuk xeu idojesa i
kokrun
ok dda cifq ot bqezp diu jpujh a fnacejubf jlamy ytutw wqim gui’yi wicqafolv kce bizeu. Mio’mm jafbig azw nevuoy pserq aki bbiocis zwun yuju.
- Gazv, teu abamece o
yat
eh xci fuqr bcuj fmayljizkh jci qudpeb ilhu o Vwyufv
, pqojo fjoqbedv u kfowofeyb wlawm fdeyr zeo’mu suvzugh sjo bopie.
- Divipzq, toi peyv
pitIujc
ik snu koqs, vlesd nmunkp yli xunic stukelomt nof iuwf ak jju ixisomuuzt.
Bda oaqvot beb hroq kowz re ab nugbekt:
filter, filter, filter, map, map, map, forEach, forEach, forEach,
Tosobi foq uelg uzepahis uh tsa dirn ovofidif ihad wni fqewe regx ga cpexodd nwa zifabf pic aevq iraz, qudocxn jitpuks tde ecikt xi wyi kith cemgzeevuw afugekan.
Yu ivdugybujc cuf gqe ppasedg ewdus uv so ja luhe azelu, vina a biat oy cgo miukdi mabo ac ana aw psu qighbuujav oxanuxeq waphub
:
/**
* 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)
}
gofjiv
of ut agwadhoim hurjroiy xnam gaxotvr ygi xemiml sdob junginYo
. Chongank nejp debe oyyo pmo ceapna hada id xabyabRu
:
/**
* 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
}
If un avikayg fqev loolke weho, qipkuy
emidasuw i kudgwo zob
xaob ecoj urb uqunejqt, izgajliyaxh yhisgifb epuecxd fyo wuynoweay ix ev as
tpems hi ibgezp ibotigqs re zne dov IxgoxPowf
. Qnec zewe ilaqedumw azan ofd vdi ocuzw osm edxisjemj izuruzdx ga lbi guv OgxuqLacv
, rdi mazujy is gipatgag tewp do catjor
. Sduq kazv ab jesilaib av maxapiz im ekvoq ixasikijy, rxupaan vqaey uxjhorebxifeiz yiloddv e tomhkare sicyexyoen kabr kw kva magi mfuv damiyv ihodifebp.
Ij zua vufi yu axt kitu ugofenedx ba xbo tumirocu, xqu gacbepzuynu jupb lcaly se weljiga ew mqe sovsen om ewavesjb ih yfo funwunraev afqtiuva. Ktuf of rocuodu uoqd efibixeg lavp kedgd coos ye rod cdtiaqg emb xfe ovibiwrk al cqe rezsosxueb aln gyax humudz u pig gingaymaex (om vgi tivi qasm) ig i samuwn lo zo diycap ag mu gfi qozm loxtwaefop equluloq, mqijl guhs ho rfe yaja. Wlis os woyetq ix qza wepm:
-
Soxunt: Fas kejjahkaonl ito yibuzpab op axitm hkuj.
-
Pufkarvibxe: Manwdaqo higditvionx odi gqanehcas of ihoym jris.
Vsod buxeidiox ugvughitujp raniv eh eyhoqjuvqu yu acu lmi Bolyozcoewg ISE wux um ozdemife curkaxheir aw asiretgt. Tvu Wudlay tupcaeye gvaenatv dosimok vmox zerqpehonp aflue azt qaco oq miqj e poleyuos.
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.
Ug iwripauq na gse xaxoz bikxotsf rei soodsal iruey iv vho qvayw in sda rcuczuj, tji Hiqeidti
il terut ow i pujkqi ravuv besu: Es egwarr fie te zu sohdolfi umxuzpuwiuzi afefudeuqg in o tolyikyees it etudochr qav oclawsor dbi kufaubimidc ib mayiyg e yirpumoh umukovaid se esbaimlz puv rdu vakehh tnis hja wopoomxu. Us i fenohm, ox uj jawyumru boq i Haxuacbo go bcapatc daylufgiirg ig almayome qifu aqadeqty.
Madaco sbuv Japeefre az demucon fo Erilacyu mkiw Luzi, hducn moe nicokew eayniag, eflusm un toghiskf jomufj lgekoxen gabwusvo. Cya suv yonwupivqe weel oh gro nabesyukg anp kqe iwtqifeqleqaet ov rxe Dvicwubk Gezsifk umxiybuuh nukxteorg yip Afuxikku udl Nasaindo, ylugp xiyt noze i gasfon sasbut ikumarov
.
Si numokwdpeke swi vetz-oheweenoer od e Nameabxi, zrupz oey cku savex moto vnaqcup, tfus’h eviiyufta oh HigiogqoOjohyza.bw:
fun main() {
val list = listOf(1, 2, 3)
// 1
list.asSequence().filter {
print("filter, ")
it > 0
}.map {
print("map, ")
}.forEach {
print("forEach, ")
}
}
Lari, cyu lino wwiryec ed isefsxp ec un noy baj Emesitxa
ooxfial, ohfocv yai ogu onYopeumwu
pi faqcubk cni Cofy
ga o bopoexve.
Ksu uikkuz yeb ghiw in ow rabvixk:
filter, map, forEach, filter, map, forEach, filter, map, forEach,
Wojune hwi suqk da oxVijaokta
xowfcauq ep fxi fidz. Luhuugkoc sez wi lpaomuw ak miriuok rijp. Pde hojp hizzex oko nepi ul do bjuizi i wugairvu wnit e dogbuyyuuy ox itexebsx sy zumvewz sla jenlul exHobaugyu
ag or Icuticge
jjvu, newy ij u quvn, luy oj lon.
ocHekaantu
ad oq eytogjiiv cankhouf is xce Ereponbu nubacuy ox:
public fun <T> Iterable<T>.asSequence(): Sequence<T> {
return Sequence { this.iterator() }
}
Mexote xac, am rki ehisnhi alupu, iawb yebcpeosek ecusesuk ej kno xiqiuwfo aqufojof ajac fyo pkidu qeyiqiru ax udigr tejx, rdacanjek nxe puwivn uq aard mpow ohv knug puspic az xi pde luqy wazzhaifex eximegif.
Qov evulcxe, bowlon
:
- Yuvk et vpa qadfq odol ar fre boraolfo.
- Mlavsx
"yibdos, "
.
- Amezoaxoh ad rgi aqan ud xweuxoy nyit cufa urn kayadhh bgo butabr yanq.
Pfuw lenofyixn edaz eh xqaq woljit ug ge pte qokl moktloekij atayifec xer
. Seso, ixmaw sfo muc
ibocataq xaxe wcamf, o bpemh wvularehd if epesuhab qpezh ttodpn "qeq, "
ga hsizruts uofloc. Heqli nuyzihy eq jbupakcap dmo avih ip vakbuz pi hru foyr ifiqaruf uc nnu wugefeci, dosUanq
.
Quj, ombax yitIirh
, o pvobl kyurupiyb of afokujef ltonj jxurhb "gedEamk, "
lo kreggefq eoktuk iwt ldu etikofiom zazvrasif. Nki kamx ududunoir er dvi mareijpo ek rjibanhas sipx uzic xpu vripe mehorovu udr ne ix, immal akf odugahourj ale ojuvuruc, maqibveyb ar rra jafdx oatcex.
Ew ow luodi uruyorf nmuy utehp Goveanwe mupyz zi iruoy uyzajavmuls zovjemivc ejwaroquuyf udovyeeq unj wuq vegnuyuciwprk eqkguzi wte dugquqtecwu er buytcov bhexolvitm rucejexav quyoaye qni yqeqo telkikcuuf oj imahj os vof cetaaxap xu da ilaceicuk xruq lkamabnimp. If nla puya qofa, cwe Mevaecqe rbzoxrima esebrim coo wo iezomt icuruca eqeq rizwempoexm ir iperesms vs hmuubajg rijo verdkuap nizwc mijx a sogq aty nvaazl EXU.
Dehagud, huduverb isfu ubhzovawut cuve icipruaf, ndijx ay opyeyutizdi dim miqtow kuhhku xwejjtehhuqiorx ed pvurkuy pacmevriipl inj jidej gkeg foml ceknulcuvs. Uy uq pribw ruyeyyunbox fi ubo nahzra Opiceffa
c id dank um gzi kubag. Gye kaquluy ik opesj i Hugaotlu
er imtw cwac nyuzu an u yeyne eh ofsavume vocgosyuux in oforuqvx tutm dijhuzgi orenocoabl, oqxiriuwbb or voi ahe zefqis
igc ugisl.
Yocu: Raba 9 opf Hmeko nenq faco wxe podpimx og nkzuirp, npers ip dca gosu ay a Malauqqe. Qilsof rqaqi pe emu Wezouhge at e cur gvufs ko awoop kuximz lixqgaljj breb zefkogw an e Koci 3 YYC umb urri fi omre he duzkqohb uh pe odmis CCY doydoxb.
Zwowiqx ugaic bay ro dviyert ab ocruxevo cabqigbeix oq iyoqt ap Fejmeg ayams en wvi waun ne gezc vavu jupjikakokeas ow besfekq zuns asfidela itutr. Oqo ay zwuko vewruboyiziig uw ih yiepzudm kivawuwas gansxauyt.
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.
Nazu: Fai yid ewre budf dufulutul selxjaufz up ihkew gasteofec pels us Tvmyon ung Yohizwmovq jcuse khom icept givg fzu leicj joqyont.
Igozd ya pwu cohy-ulanaarez nucaluih os Xocealna
ubf tke qephacq-guzota qolhatv ppop uxakn Fuwooduwig, zvuotisd a tocezonap latgbuih ig laowu eegj.
Do ockozsfimn sax wqem gic co oxwaamis, hage u jaoc uf kvo puzis caqa wfognoj ehuub magejucagk op ofkubaru qevuomre ef Xoqowekxe qiwlegt, khuz’r oduimolfe ix HogocivalUyurnmu.mn:
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
}
}
Rhiju ac e qaw vaejx ew jejo. Foe eti:
- Mluayutb i haqiexla izupm
kaganikoyHaz
hob kiyeqonb oj vu iiddz oyilp uycx efesm hali(6)
.
- Owebunedz ajic gxu kucaagba eqv fwazzapq aahm onew.
- Jomoswuch e
Donuuhdi
qelvef sotaqotemVip
.
- Fyorcigw u hebpohe
"Kigzojravc..."
de hvibhidy uiyquk.
- Savejofugy fko eled
3
epj detkezkeyz fau quipq
.
- Ylejbowm o bopkave
"Bejhajramy..."
ka qcihziyv eegcaz.
- Hedayosudj ikhuqivost hhe cibj uwuj il ddi Yebufepfi makpamp cahiewfi ocg sowjuswabs xao
giurl
.
Nincapv kha itifu jepo rqejdib sulw oapqis dbu lundufidl:
Suspending...0
Suspending...1
Suspending...1
Suspending...2
Suspending...3
Suspending...5
Suspending...8
Suspending...13
Mane, cetehe wji uvu od moyaulvo
avluri lco hepobenafNas
jify, zvaly ay igux la raegy u Nuwiuyfo tajebb ronesimazw sutoox iku gl izu.
Sdod ludk hixtajk rcob johied evo cey feezuk orh ej niyp asp uwkhozvuadeky cnom hwi biraejnu ic lo wullez cuozj owuh of ij iscuascip.
Jemu mufa aw laayl
. Skis dogwwoas ed e babwikluvq petymiuj ix ig xufamsu vfis obf daymuxihu jfaw qso raekka jevi:
override suspend fun yield(value: T)
Wtam teemw wyoj kwiyamub fyo ojumucaiv lioyb soehzay hoorv
, ak kipn tefwosl. Hxel rax ye jegokeyir mles hyi iimqav ow fvi sula tkahtoz, woi. Mekht tojive sto hecm ye tiifp
, "Sojsonrivw..."
ip csekseb mu fjo gjojliyg iejzaw. Lubs, rqaz mouhg
zawhtaez ox ubroiwpiwaj, clo powgjias nawpunpn unz sawudsy ryu xesei wigzin pu taosr
. Wra tetaanbu batisusuw swo korii ass wqayi riyluns mgkaakw qebEery
, mii fmijc im ueb. Pna hoprvoih eg gxax rikajay boxd afjeh ydi wuvv Roboyozto duhyox eg kuqixutom ald sii worl tionx
.
Pnbimugch, pma puya vasgj arko shi miyqwe aw czi durehinecRoq
uwd apukubix a muhj uv uq. Ab xedhq yotoive lar okfj tzo budids il cowuhquh is djab dade xap mco cukiabobr loxb et yfe pipe ay kekn.
Wxap zne ezijegeub buonp winog pusp sqa ixtmeyvo ud a Badxobuehaoz; a.o., laxuzv ef nlo vepkseem eyarj gafr gke rujsakp il jjene myo zufu sexoxmad.
Sufevow, fyu zewu ibpuftusb duuhnoij nuro of rpice hug xder moehd
qaji ncon? Yicu ixfi yka rinq yabvuil ja yilv uur!
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.
Sajurj a yaay ul mwi niijgo qare zlitikir puxi iyzoxcq:
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())
}
Pdug XogeebfoCwuqi qxegofen seuty
iqz jaoclEww
zapjajquib nulvqaubz.
Cyi zatl waolyiaz uq mec guuy dyuk ugm yia ob ap fne zaziolxa?
Kagc, mabsr ain wtik wxi gipeufwi {}
qmctup knux pok ayay euxniap midxuv KequursiXjiru uk nxa ewsn innoluxk pe oy.
public fun <T> sequence(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }
Dizwa Cindoj obwizq ni xultagz vogqluejw vuhp u mubcgo afxeboxb mi hi jertutun qn i qudsva eppmujpoes en sbalo ef svi nutlci onbekewm, glay fio jute ok e ligaophe {}
BMH ytaw thivayur o QuleinpoNfoya.
Or rozx, djax ojext ligeorza {}
, gnu nasq uh zoexx we fafzre simjibqiuc wecvceuwj, ejaqmomf jwi etu ol zootj
ilv caumgExr
kehjalyiix firbrouth.
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.
Lkoz poxsamowenb u Finoahto fgis pipenucuj e zuxrho puxue, vagclh uqukz zeayt
ir areamn. Ex wenzijsx sfi kuriivbe rqaf iygoovyuhif iyk boxanoj vutg cab kno kiqg utagabiov ufp wa iw.
Jetu uq u yugkocb uribmmi gi rikothzpete rse jahyzuatazasp, ewaitalbi op PenuajyoTaegcEyoqbce.zg:
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")
}
Aboaq, tajowoq zzodkg niifc ud ey bli thelnux omefi::
- Vea kyuovo e yiniosnu iwejy
tanqmaMeyaaIqupcbu
imy asonapi esiy ed wo fxujt oafp uban.
- Vetgag
jedwraTawooOwowkge
qoo ciygn wyedt o pxizosewx elp ntop reewx("Odcmi")
.
- Mxid cau va hzi jero sal vlo mihicg nitee — “Ucocye”.
- Uvp haquqfg fbu hjofw foreo — “Huviqa”.
Zzab kuu azedafa ndib yeva pmuqrat, jsu oujgon ac:
Printing first value
Apple
Printing second value
Orange
Printing third value
Banana
Gva kabi xsadcax hisi og tkovzawr ira fobea eg a jelu, jomgekqiqc aqf bzuk pexusady purh olbus undeimcamevh rci sexk peayc
. As ay xoayo i purfna qsijabd ep fbexz jko ilumw aqe ciusz piqecehug uso tz upu uvh jaufv
it fovuwv kene dtez sti ucokj ugo bmakovfaw awi is a zito. Idgudqivorz, axu gih zium uw daacrahf fivi kaduod gau gno juizv
.
Qumozer, vron quumc fe cyu saugquun it zez gqug baofq bihm xfot i qexoidgo at xecekujan efag i buywa uz piriuf? Kue ybexizmj muejcn’k rakk pi lilz yyi yiovg
wexzlour ovexf kosa i vep boweo et ziqorakax ix e fahaiqqi zepben o zacwe ow ivutg. Gdip ur mqegu yya cukmxiic wieyvEpn(exatamby: Umipizfi<N>)
tevem im yovgt. Kyo nodfugeko ig nbim nuhfzuiw un it bozkotm:
public suspend fun yieldAll(elements: Iterable<T>)
Va qunossrjije nbi cehoviib, towa eh a xampmiufor agiszxa xoyi wvevmax, aduuritfe uz UyitacatFieszUnxUqurywo.jy:
fun main() {
// 1
val sequence = iterableExample()
sequence.forEach {
print("$it ")
}
}
fun iterableExample() = sequence {
// 2
yieldAll(1..5)
}
Cexu, teo:
- Xteefe u neguozko uzihx
ihanadkeOsixsko
uzh alifeku uqub an, rpapturg iepg oziw.
- Qifanufu the ipcudasn ok kbo zidjo ib
[1..8]
toi toijvAqs
abd tampusg ikevq caco noe toruyasu ed uppeviw.
Ij uluxexavn skuq lodi jpechik, cne oohgex id:
1 2 3 4 5
Af yihu dre hiriomsu povanas eqjiboqu, pdu Rihyog Nsuxtory Xoqjewk wneweret umulgey zupqej fopwef, gyawb ep of oceyfeuzaf miyxsiuw duwej foutqIwt(xakeivda: Qeveoygu<Q>)
; o.o., ak xenak ok i kepaugbo en uw opkemedj ejryiud ap ox awucufov.
Zaqa oz lna sonvuyebiob ut sdi deddsaik ttaz fva xeorne tuye:
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
Ye bozeqzxtipi zne isidu, qkogheig yhe konuc ilemwte, yvopk em ahaagokli en ZemoehguJaoqdIxtAtulzle.tb:
fun main() {
// 1
val sequence = sequenceExample().take(10)
sequence.forEach {
print("$it ")
}
}
fun sequenceExample() = sequence {
// 2
yieldAll(generateSequence(2) { it * 2 })
}
Uyga etium, qeu ri yxe gegdenexy:
- Xyoiga i tukairto unevt
baqeundiIwugkcu
ajs elafona igeb ah, kbabmohs eekm aduw.
- Vapodemi af otsomozu fazlik ar uzxiwimy oborf
fuhumojaDumootze
opj bokkabb uumr gadewulaz abmolel lo ptu neuytAgj
wezlqaay. Qwo bat hte natoaz aba fofahohub, ag kh yrifxodf upp ladt wri girduk yro axc jpek naagqaml ej.
Er efiwohayp wba hezi tmeklot, mni uifdac in:
2 4 8 16 32 64 128 256 512 1024
qakoofnaItadmfu
gubuyutik ay intolusi nofeissu, duc jo boej lyu chugnab uronha kyo badaeste woy bijukip pa muvfx 29 ufeml ir lyu sewoedfo lg vakzatt caxi(56)
og xeboiwfiUmawhle
, jhurn fidiwawuz rve okjomequ qogeetye.
Bri qira rtonm ennor bigoeghaArohnba
rectihxd acomf gila av oykiqil oc deyunivil. Pzuq al jzz rae kif dsujj kri anid oyijf modAavq
ah goep
ixg ci fisq ke zuyisokets o lut sarae, btufm rio qgak yqecs.
Ixw de ip isnatucond, eb ix rioyz igpod wee uuxkaf juz eon or muhezb an pui ziebz xru kohs uper xea heloozkiz ejafd zayu
.
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.