Sobes.tech
Middle

Kotlin-də axınlar (streams) ilə necə işləmək olar?

sobes.tech Süni İntellekt

AI-dan cavab

Kotlin-də məlumat axınları ilə işləmək üçün (Java 8 Streams API-ə bənzər) kolleksiya üçün genişləndirmə funksiyaları istifadə olunur, bunlar standart funksiyalar kitabxanası tərəfindən təmin edilir. Bu, ayrıca API deyil, kotlin.collections-də təqdim olunan metodlar toplusudur.

Əsas axın əməliyyatları aşağıdakı kimi bölünür:

  • Müvəqqəti (Intermediate operations): Yeni kolleksiya qaytarır və "lazımi" (yalnız son əməliyyat çağırıldıqda icra olunur). Nümunələr: filter, map, flatMap, distinct, sorted, take, drop.
  • Son (Terminal operations): Əməliyyatlar ardıcıllığını tamamlayır və nəticəni qaytarır (kolleksiya deyil). Bütün müvəqqəti əməliyyatları icra etməyə səbəb olur. Nümunələr: forEach, reduce, fold, count, sum, average, min, max, toList, toSet, toMap.

Həmçinin, silsilə axınlar (sequences) anlayışı mövcuddur və bu, açıq şəkildə lazımi icraatı təmin edir. Sequences elementləri tək-tək, ehtiyac olduqda işləyir ki, bu da böyük kolleksiyalar və ya uzun əməliyyat zəncirləri üçün daha effektiv ola bilər:

  • Silsilə yaratmaq: collection.asSequence()
  • Yenidən kolleksiya kimi çevirmək: sequence.toList()
// Standart funksiyaların axın emalı üçün nümunə
fun processCollection() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    val evenSquares = numbers
        .filter { it % 2 == 0 } // Müvəqqəti əməliyyat: cüt ədədləri filtrləyirik
        .map { it * it }     // Müvəqqəti əməliyyat: kvadratını alırıq

    println(evenSquares) // Son əməliyyat: kolleksiyanı göstərir (filtrləmə və map icra olunur)

    val sumOfOdd = numbers
        .filter { it % 2 != 0 } // Müvəqqəti
        .sum()                // Son (icra olunan): tək ədədlərin cəmini hesablayır

    println(sumOfOdd)
}

// Silsilə istifadə nümunəsi
fun processSequence() {
    val largeCollection = (1..1_000_000).toList()

    // Kolleksiyalar ilə (lazımsız): filter və map bütün elementlər üçün icra olunacaq
    val resultCollection = largeCollection
        .filter { it % 2 == 0 }
        .map { it * 2 }
        .take(10) // take(10) bütün elementlər üçün filter və map-dən sonra icra olunur

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

    // Silsilə ilə (lazımi): filter, map və take element-ə əsasən icra olunur
    val resultSequence = largeCollection.asSequence()
        .filter { it % 2 == 0 } // filter hər element üçün icra olunur
        .map { it * 2 }     // map hər keçmiş element üçün icra olunur
        .take(10)         // take(10) 10 elementdən sonra işləməni dayandırır

    println("Result Sequence size: ${resultSequence.toList().size}") // toList() silsiləni icra edir
}

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

Standart funksiyalar və sequences arasındakı müqayisə cədvəli:

Xüsusiyyət Standart kolleksiya funksiyaları Sequences
Lazımi Müvəqqəti əməliyyatlar üçün qeyri-şüurlu, amma son əməliyyat bütün zənciri tam işləyir Aydın lazımi: əməliyyatlar ehtiyac olduqda element-ə əsasən icra olunur
Effektivlik Böyük kolleksiyalar və uzun əməliyyat zəncirləri üçün daha az effektiv ola bilər Böyük kolleksiyalar və uzun zəncirlər üçün daha effektiv
İstifadə Kiçik və orta kolleksiyalar üçün uyğundur Böyük kolleksiyalar və ya erkən dayandırıla bilən əməliyyatlar üçün uyğundur (take, find, first, any, all, none)

Standart funksiyaların kolleksiya üzərində istifadəsi adətən kifayət edir və daha qısa olur. Sequences isə böyük məlumatlar ilə işləyərkən performansı artırmaq üçün açıq lazımi icra üçün tövsiyə olunur.