Sobes.tech
Middle

Kotlinде агымдар (streams) менен кантип иштеш керек?

sobes.tech AI

AIден жооп

Котлинде маалымат агымдары менен иштөө үчүн (Java 8 Streams API сыяктуу) кеңейтүү функциялары колдонулат, алар стандарттык функциялар китепканасынан берилген. Бул өзүнчө API эмес, kotlin.collections аркылуу берилген методдордун жыйындысы:

Агымдар менен негизги операциялар бөлүнөт:

  • Орто (Intermediate operations): Жаңы коллекцияны кайтарат жана "сабырдуу" (тек гана терминал операциясы чакырылганда ишке ашат). Мисалдар: filter, map, flatMap, distinct, sorted, take, drop.
  • Терминал (Terminal operations): Операциялардын тизмегин аяктап, натыйжаны кайтарат (коллекция эмес). Бардык орто операцияларды ишке ашырат. Мисалдар: forEach, reduce, fold, count, sum, average, min, max, toList, toSet, toMap.

Мындан тышкары, жылдамдык агымдары (sequences) концепциясы бар, ал ачык сабырдуулукту камсыздайт. Sequences элементтерин керектүү учурда бирден иштетет, бул чоң коллекциялар же узун операция чынжырлары үчүн натыйжалуу болушу мүмкүн:

  • Агымды түзүү: collection.asSequence()
  • кайра коллекцияга айландыруу: sequence.toList()
// Стандарттык функцияларды колдонуп агымдык иштетүүнүн мисалы
fun processCollection() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    val evenSquares = numbers
        .filter { it % 2 == 0 } // Орто операция: жуп сандарды фильтрлөө
        .map { it * it }     // Орто операция: квадраты

    println(evenSquares) // Терминал операциясы: коллекцияны чыгарып көрсөтүү (фильтрлөө жана map ишке ашат)

    val sumOfOdd = numbers
        .filter { it % 2 != 0 } // Орто
        .sum()                // Терминал (жеке сандарды кошуу)

    println(sumOfOdd)
}

// Агымдар менен иштөө мисалы
fun processSequence() {
    val largeCollection = (1..1_000_000).toList()

    // Коллекциялар менен (сабырдуу эмес): filter жана map бардык элементтер үчүн иштейт
    val resultCollection = largeCollection
        .filter { it % 2 == 0 }
        .map { it * 2 }
        .take(10) // take(10) фильтрлөөдөн жана map-тан кийин бардык элементтер үчүн иштейт

    println("Result Collection size: ${resultCollection.size}")

    // Агымдар менен (сабырдуу): filter, map жана take элементтер боюнча иштейт
    val resultSequence = largeCollection.asSequence()
        .filter { it % 2 == 0 } // filter ар бир элемент үчүн иштейт
        .map { it * 2 }     // map ар бир өтүп кеткен элемент үчүн иштейт
        .take(10)         // take(10) иштетүүнү 10 элементтен кийин токтотот

    println("Result Sequence size: ${resultSequence.toList().size}") // toList() агымды иштетет
}

fun main() {
    processCollection()
    processSequence()
}

Стандарттык функциялар жана sequences салыштыруу:

Өзгөчөлүк Коллекциялар үчүн стандарттык функциялар Sequences
Сабырдуулук Орто операциялар үчүн жасалма сабырдуулук, бирок терминал операциясы бардык орто чынжырды иштетет Ачык сабырдуулук: операциялар керектүү учурда бирден ишке ашат
Натыйжалуулук Үлкен коллекциялар жана узун чынжырлар үчүн натыйжалуулук төмөндөйт, орто коллекциялардын эсебинен Натыйжалуу, чоң коллекциялар жана узун чынжырлар үчүн
Колдонуу Кичинекей жана орто коллекциялар үчүн ылайыктуу Ийкемдүү, чоң коллекциялар же эрте токтотуучу операциялар үчүн (мисалы, take, find, first, any, all, none)

Стандарттык функцияларды колдонуу көбүнесе жетиштүү жана кыска. Sequences колдонуу чоң маалыматтар менен иштөөдө натыйжалуулук үчүн сунушталат.