Kuidas töötada Kotlinis voogudega (streams)?
sobes.tech AI
Vastus AI-lt
Kotlinis kasutatakse andmevoogude (Java 8 Streams API analoog) jaoks laienduste funktsioone kogumite jaoks, mis on saadaval standardfunktsioonide raamatukogus. See ei ole eraldi API, vaid meetodite kogum kotlin.collections:
Peamised voogude operatsioonid jagunevad:
- Vaheoperatsioonid (Intermediate operations): Tagastavad uue kogumi ja on "hoolikad" (täidetakse ainult siis, kui kutsutakse lõplik operatsioon). Näited:
filter,map,flatMap,distinct,sorted,take,drop. - Lõplikud (Terminal operations): Lõpetavad operatsioonide jada ja tagastavad tulemuse (mitte kogumi). Täidavad kõik vaheoperatsioonid. Näited:
forEach,reduce,fold,count,sum,average,min,max,toList,toSet,toMap.
Samuti on olemas kontseptsioon — järjepidevad vood (sequences), mis tagavad selge "hoolika" (aeglase) täitmise. Sequences töötlevad elemente üks korraga vastavalt vajadusele, mis võib olla tõhusam suurte kogumite või pikkade operatsioonijada puhul:
- Voogude loomine:
collection.asSequence() - Tagasimuundamine kogumiks:
sequence.toList()
// Näide standardfunktsioonide kasutamisest voogude töötlemiseks
fun processCollection() {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenSquares = numbers
.filter { it % 2 == 0 } // Vaheoperatsioon: filtreerib paarisarvud
.map { it * it } // Vaheoperatsioon: ruudud
println(evenSquares) // Lõplik operatsioon: kuvab kogumi (täidab filter ja map)
val sumOfOdd = numbers
.filter { it % 2 != 0 } // Vahe
.sum() // Lõplik (summa arvutamine)
println(sumOfOdd)
}
// Sequences kasutamise näide
fun processSequence() {
val largeCollection = (1..1_000_000).toList()
// Kogumitega (mitte aeglane): filter ja map täidetakse kõigi elementide jaoks kohe
val resultCollection = largeCollection
.filter { it % 2 == 0 }
.map { it * 2 }
.take(10) // take(10) täidetakse pärast filter ja map kõigi elementide jaoks
println("Result Collection size: ${resultCollection.size}")
// Sequences-iga (aeglased): filter, map ja take täidetakse üks element korraga
val resultSequence = largeCollection.asSequence()
.filter { it % 2 == 0 } // filter täidetakse iga elemendi puhul
.map { it * 2 } // map täidetakse iga läbivaadatud elemendi puhul
.take(10) // take(10) peatab töötlemise pärast 10 elementi
println("Result Sequence size: ${resultSequence.toList().size}") // toList() käivitab sequence'i täitmise
}
fun main() {
processCollection()
processSequence()
}
Võrdlustabel standardfunktsioonide ja sequences'i kohta lühivõrreldes:
| Omadus | Standardfunktsioonid kogumitele | Sequences |
|---|---|---|
| Aeglus | Kaudne aeglus vaheoperatsioonidele, kuid lõplik operatsioon töötleb kogu jada täielikult | Selge aeglus: operatsioonid täidetakse üks element korraga vastavalt vajadusele |
| Tõhusus | Võib olla vähem tõhus suurte kogumite ja pikkade operatsioonijadade puhul, kuna kasutatakse vahekollektsioone | Tõhusam suurte kogumite ja pikkade operatsioonijadade puhul |
| Rakendus | Sobib väikestele ja keskmise suurusega kogumitele | Sobib suurtele kogumitele või operatsioonidele, mis võivad varakult katkeda (take, find, first, any, all, none) |
Standardfunktsioonide kasutamine kogumitel on sageli piisav ja lühem. Sequences soovitatakse, kui on vaja selget aeglust, et optimeerida suurte andmekogumitega töötamist.