Sobes.tech
Middle

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.