Kotlin: شرح عمليات المجموعات في كوتلن

آخر تحديث: 2026-08-26

عمليات المجموعات في كوتلن تتيح لتشارلي استبدال الحلقات الأمرية بخطوط أنابيب تصريحية — سطر واحد يغني عن 15 سطراً من حلقة for، بنية أوضح.

1. ما ستتعلمه


2. قصة مهندس حقيقية

(1) نقطة الألم: OOM عند معالجة ملايين الطلبات

استخدم تشارلي List لمعالجة ملايين سجلات الطلبات. كل عملية وسيطة أنشأت مجموعة جديدة، تستهلك 3 جيجابايت من الذاكرة مما تسبب في OOM.

(2) حل التقييم الكسول مع Sequence

KOTLIN
// متحمس: ينشئ مجموعات وسيطة في كل خطوة
orders.map { enrich(it) }       // المجموعة 1: مليون عنصر
      .filter { it.total > 100 } // المجموعة 2: ~500 ألف عنصر
      .toList()                   // المجموعة 3

// كسول: يعالج عنصر واحد عبر الخط بأكمله
orders.asSequence()
      .map { enrich(it) }
      .filter { it.total > 100 }
      .toList()  // مجموعة نهائية واحدة فقط

Sequence كخط تجميع: كل عنصر يمر عبر الخط بأكمله قبل أن يبدأ التالي — لا حاجة لمجموعات وسيطة.


3. العوامل الأساسية

(1) map — التحويل

KOTLIN
val orders = listOf(
    Order("ORD-001", 299.99, "Alice"),
    Order("ORD-002", 1_500.00, "Bob")
)

// تحويل كل عنصر
val ids = orders.map { it.id }                // [ORD-001, ORD-002]
val summaries = orders.map { "${it.id}: \$${it.total} USD" }

// mapIndexed: مع الفهرس
orders.mapIndexed { i, order -> "[${i + 1}] ${order.id}" }

// mapNotNull: تحويل + تصفية القيم الفارغة
val emails = orders.mapNotNull { it.customerEmail }

(2) filter — التصفية

KOTLIN
// تصفية حسب الشرط
val highValue = orders.filter { it.total > 1_000 }
val pending = orders.filter { it.status == "PENDING" }

// filterNot: تصفية عكسية
val active = orders.filterNot { it.status == "CANCELLED" }

// filterIndexed: مع الفهرس
orders.filterIndexed { i, _ -> i % 2 == 0 }  // الطلبات ذات الفهرس الزوجي

(3) flatMap — التحويل المسطّح

KOTLIN
data class Customer(val name: String, val orders: List<Order>)

val customers = listOf(
    Customer("Alice", listOf(Order("ORD-001", 299.99), Order("ORD-002", 150.0))),
    Customer("Bob", listOf(Order("ORD-003", 1_500.00)))
)

// تحويل + تسطيح في خطوة واحدة
val allOrders = customers.flatMap { it.orders }
// [Order(ORD-001, 299.99), Order(ORD-002, 150.0), Order(ORD-003, 1500.0)]

(4) groupBy — التجميع

KOTLIN
// تجميع حسب المفتاح
val byCustomer: Map<String, List<Order>> = orders.groupBy { it.customer }

// تجميع مع تحويل القيمة
val totalsByCustomer = orders.groupBy(
    keySelector = { it.customer },
    valueTransform = { it.total }
)
// {Alice=[299.99], Bob=[1500.0]}

(5) associate — الربط بـ Map

KOTLIN
// إنشاء Map من قائمة
val orderMap = orders.associate { it.id to it }
// {ORD-001=Order(...), ORD-002=Order(...)}

// associateBy: منتقي المفتاح
val byId = orders.associateBy { it.id }

// associateBy مع تحويل القيمة
val totalsById = orders.associateBy(
    keySelector = { it.id },
    valueTransform = { it.total }
)

(6) مرجع سريع للعوامل

العامل الوظيفة الإدخال → الإخراج تشبيه SQL
map تحويل List<A>List<B> SELECT
filter تصفية List<T>List<T> WHERE
flatMap تحويل مسطّح List<A>List<B> JOIN + SELECT
groupBy تجميع List<T>Map<K, List<T>> GROUP BY
associate ربط List<T>Map<K, V> -
distinct إزالة التكرار List<T>List<T> DISTINCT
sortedBy فرز List<T>List<T> ORDER BY

4. خط أنابيب عمليات المجموعات

100%
flowchart LR
    A[طلبات<br/>مليون سجل] --> B[filter<br/>total > 1000]
    B --> C[map<br/>استخراج العميل]
    C --> D[distinct<br/>عملاء فريدون]
    D --> E[groupBy<br/>حسب المنطقة]
    E --> F[النتيجة<br/>Map من العملاء]

5. التقييم الكسول مع Sequence

(1) متحمس مقابل كسول

KOTLIN
// متحمس (List): كل خطوة تنشئ مجموعة جديدة
val result = orders
    .map { println("map: ${it.id}"); it.copy(total = it.total * 0.9) }
    .filter { println("filter: ${it.id}"); it.total > 100 }
    .take(2)
    .toList()

// كسول (Sequence): يعالج عنصر واحد في كل مرة
val result2 = orders.asSequence()
    .map { println("seq-map: ${it.id}"); it.copy(total = it.total * 0.9) }
    .filter { println("seq-filter: ${it.id}"); it.total > 100 }
    .take(2)
    .toList()
// Sequence يعالج العناصر فقط حتى يُلبى شرط take(2)

(2) متى تستخدم Sequence

السيناريو استخدم List استخدم Sequence
حجم البيانات < 10,000 > 10,000
خطوات العملية 1-2 خطوة 3+ خطوات
حجم النتيجة الوسيطة قريب من حجم المصدر مُقلص بشكل كبير
حاجة لاجتيازات متعددة نعم لا

(3) أداء List مقابل Sequence

البُعد List (متحمس) Sequence (كسول)
المجموعات الوسيطة تُنشأ في كل خطوة لا تُنشأ
الذاكرة O(n × خطوات) O(1)
عمليات الدائرة القصيرة غير محسّنة محسّنة (مثلاً take يعالج N فقط)
أول نتيجة تنتظر الخط الكامل متاحة فوراً

6. عمليات التجميع

(1) fold / reduce

KOTLIN
// fold: مع قيمة ابتدائية
val totalRevenue = orders.fold(0.0) { acc, order -> acc + order.total }

// reduce: العنصر الأول كقيمة ابتدائية
val maxOrder = orders.reduce { max, order ->
    if (order.total > max.total) order else max
}

// foldRight: من النهاية إلى البداية
val reversed = orders.foldRight(emptyList<Order>()) { order, acc -> acc + order }

(2) التجميع المريح

KOTLIN
val total = orders.sumOf { it.total }
val avg = orders.map { it.total }.average()
val max = orders.maxByOrNull { it.total }
val min = orders.minByOrNull { it.total }
val count = orders.count { it.total > 1_000 }

// الفرز
val sorted = orders.sortedByDescending { it.total }
val top3 = orders.sortedByDescending { it.total }.take(3)

(3) fold مقابل reduce

البُعد fold reduce
القيمة الابتدائية يجب تحديدها العنصر الأول ضمنياً
المجموعة الفارغة آمن (يرجع القيمة الابتدائية) يطرح استثناء
نوع الإرجاع يمكن أن يختلف عن نوع العنصر نفس نوع العنصر
التوصية ⭐⭐⭐ ⭐⭐

7. المجموعات الثابتة مقابل المتغيرة

(1) واجهات القراءة فقط والمتغيرة

KOTLIN
// للقراءة فقط (واجهة ثابتة)
val list: List<Order> = listOf(Order("ORD-001", 299.99, "Alice"))

// متغيرة
val mutableList: MutableList<Order> = mutableListOf()
mutableList.add(Order("ORD-002", 1_500.00, "Bob"))

// عرض القراءة فقط لقائمة متغيرة
val readOnly: List<Order> = mutableList  // صحيح: MutableList يرث من List
// readOnly.add(...)  // خطأ: List لا يمتلك تابع add
mutableList.add(Order("ORD-003", 45.50, "Charlie"))  // يغير عرض readOnly!

(2) النسخة الدفاعية

KOTLIN
class OrderProcessor(private val _orders: MutableList<Order>) {
    // نسخة دفاعية: كشف عرض ثابت
    val orders: List<Order> get() = _orders.toList()

    // أو استخدام عرض ثابت (بدون نسخ، لكن يمكن إرجاعه بالتحويل)
    val ordersView: List<Order> get() = _orders.toList()
}

(3) مقارنة أنواع المجموعات

النوع واجهة القراءة فقط الواجهة المتغيرة دوال الإنشاء
List List MutableList listOf / mutableListOf
Set Set MutableSet setOf / mutableSetOf
Map Map MutableMap mapOf / mutableMapOf

8. مثال كامل: خط معالجة ملايين الطلبات

KOTLIN
// ============================================
// OrderProcessor - خط عمليات المجموعات
// الميزة: معالجة الطلبات بعوامل وظيفية
// ============================================

data class Order(val id: String, val total: Double, val status: String, val customer: String, val region: String)

fun main() {
    // محاكاة بيانات الطلبات
    val orders = listOf(
        Order("ORD-001", 299.99, "CONFIRMED", "Alice", "US"),
        Order("ORD-002", 15_000.00, "CONFIRMED", "Bob", "EU"),
        Order("ORD-003", 2_500.00, "PENDING", "Charlie", "US"),
        Order("ORD-004", 45.50, "CANCELLED", "Alice", "ASIA"),
        Order("ORD-005", 8_900.00, "CONFIRMED", "Bob", "EU"),
        Order("ORD-006", 1_200.00, "SHIPPED", "Charlie", "US"),
        Order("ORD-007", 350.00, "CONFIRMED", "Alice", "ASIA"),
        Order("ORD-008", 22_000.00, "PENDING", "Bob", "EU"),
        Order("ORD-009", 750.00, "CONFIRMED", "Charlie", "US"),
        Order("ORD-010", 4_500.00, "SHIPPED", "Alice", "US")
    )

    // خط أنابيب 1: الطلبات المؤكدة عالية القيمة
    println("=== High-Value Confirmed Orders ===")
    orders.filter { it.status == "CONFIRMED" && it.total > 1_000 }
        .sortedByDescending { it.total }
        .forEach { println("  ${it.id}: \$${it.total} USD (${it.customer})") }

    // خط أنابيب 2: الإيرادات حسب المنطقة
    println("\n=== Revenue by Region ===")
    orders.filter { it.status != "CANCELLED" }
        .groupBy { it.region }
        .mapValues { (_, list) -> list.sumOf { it.total } }
        .forEach { (region, revenue) -> println("  $region: \$$revenue USD") }

    // خط أنابيب 3: أفضل العملاء حسب عدد الطلبات والإيرادات
    println("\n=== Customer Summary ===")
    orders.filter { it.status != "CANCELLED" }
        .groupBy { it.customer }
        .map { (customer, list) ->
            val count = list.size
            val total = list.sumOf { it.total }
            val avg = list.map { it.total }.average()
            "$customer: $count orders, \$${total} USD total, \$${"%.2f".format(avg)} avg"
        }
        .forEach { println("  $it") }

    // خط أنابيب 4: استخدام Sequence لمعالجة فعالة
    println("\n=== Top 3 Orders (Sequence) ===")
    orders.asSequence()
        .filter { it.status != "CANCELLED" }
        .sortedByDescending { it.total }
        .take(3)
        .forEach { println("  ${it.id}: \$${it.total} USD") }

    // تجميع: fold لبناء سلسلة ملخصة
    val summary = orders
        .filter { it.status != "CANCELLED" }
        .fold("Order Summary: ") { acc, order -> "$acc\n  ${order.id} (\$${order.total} USD)" }
    println("\n${summary}")
    println("Total orders: ${orders.size}, Active: ${orders.count { it.status != "CANCELLED" }}")
}

المخرجات:

TEXT 📖 للعرض فقط
=== High-Value Confirmed Orders ===
  ORD-005: $8900.0 USD (Bob)
  ORD-002: $15000.0 USD (Bob)

=== Revenue by Region ===
  US: $7599.99 USD
  EU: $46400.0 USD
  ASIA: $350.0 USD

=== Customer Summary ===
  Alice: 2 orders, $3649.99 USD total, $1824.995 avg
  Bob: 3 orders, $46400.0 USD total, $15466.666666666666 avg
  Charlie: 3 orders, $4450.0 USD total, $1483.3333333333333 avg

=== Top 3 Orders (Sequence) ===
  ORD-008: $22000.0 USD (Bob)
  ORD-002: $15000.0 USD (Bob)
  ORD-005: $8900.0 USD (Bob)

Order Summary: 
  ORD-001 ($299.99 USD)
  ORD-002 ($15000.0 USD)
  ORD-003 ($2500.0 USD)
  ORD-005 ($8900.0 USD)
  ORD-006 ($1200.0 USD)
  ORD-007 ($350.0 USD)
  ORD-008 ($22000.0 USD)
  ORD-009 ($750.0 USD)
  ORD-010 ($4500.0 USD)
Total orders: 10, Active: 9

9. أمثلة عملية سريعة

▶ مثال: List وعملياتها الأساسية

KOTLIN
// إنشاء قوائم بأنواع مختلفة
val numbers = listOf(1, 2, 3, 4, 5)
val names = mutableListOf("Alice", "Bob")
val mixed = listOf(1, "two", 3.0)  // List<Any>

// الوصول والتعديل
println("First: ${numbers.first()}")
println("Last: ${numbers.last()}")
println("Size: ${numbers.size}")
println("Contains 3: ${numbers.contains(3)}")
println("Index of 3: ${numbers.indexOf(3)}")

// إضافة وحذف
names.add("Charlie")
names.remove("Bob")
println("Names: $names")

// عكس، فرز
val reversed = numbers.reversed()
val sorted = listOf(3, 1, 4, 1, 5, 9, 2, 6).sorted()
println("Reversed: $reversed")
println("Sorted: $sorted")

**المخرجات:

TEXT 📖 للعرض فقط
First: 1
Last: 5
Size: 5
Contains 3: true
Index of 3: 2
Names: [Alice, Charlie]
Reversed: [5, 4, 3, 2, 1]
Sorted: [1, 1, 2, 3, 4, 5, 6, 9]

▶ مثال: map و filter و reduce

KOTLIN
val orders = listOf(
    Order("O1", 100.0, "PENDING"),
    Order("O2", 250.0, "CONFIRMED"),
    Order("O3", 50.0, "CANCELLED"),
    Order("O4", 800.0, "CONFIRMED"),
    Order("O5", 150.0, "PENDING")
)

// map - تحويل
val totals = orders.map { it.total }
println("Totals: $totals")

// filter - تصفية
val confirmedOrders = orders.filter { it.status == "CONFIRMED" }
println("Confirmed count: ${confirmedOrders.size}")

// combine map + filter
val confirmedTotals = orders
    .filter { it.status == "CONFIRMED" }
    .map { it.total }
println("Confirmed totals: $confirmedTotals")

// reduce - تجميع
val totalRevenue = orders
    .filter { it.status != "CANCELLED" }
    .map { it.total }
    .reduce { acc, total -> acc + total }
println("Total revenue: \$$totalRevenue USD")

// fold - مع قيمة ابتدائية
val summary = orders.fold("Orders:") { acc, order ->
    "$acc ${order.id}"
}
println(summary)

// any, all, none
println("Any confirmed? ${orders.any { it.status == "CONFIRMED" }}")
println("All confirmed? ${orders.all { it.status == "CONFIRMED" }}")
println("None cancelled? ${orders.none { it.status == "CANCELLED" }}")

**المخرجات:

TEXT 📖 للعرض فقط
Totals: [100.0, 250.0, 50.0, 800.0, 150.0]
Confirmed count: 2
Confirmed totals: [250.0, 800.0]
Total revenue: $1300.0
Orders: O1 O2 O3 O4 O5
Any confirmed? true
All confirmed? false
None cancelled? false

▶ مثال: Set و Map

KOTLIN
// Set - عناصر فريدة
val uniqueStatuses = setOf("PENDING", "CONFIRMED", "CANCELLED", "PENDING")
println("Set: $uniqueStatuses")
println("Size: ${uniqueStatuses.size}")  // 3 (لا تكرار)

// Map - أزواج مفتاح-قيمة
val priceMap = mapOf(
    "Laptop" to 1299.99,
    "Mouse" to 29.99,
    "Keyboard" to 79.99
)
println("Map: $priceMap")
println("Laptop price: \$${priceMap["Laptop"]} USD")

// إضافة وتعديل
val mutablePrices = priceMap.toMutableMap()
mutablePrices["Monitor"] = 499.99
mutablePrices["Mouse"] = 24.99  // تعديل
println("Updated: $mutablePrices")

// التحقق من وجود مفتاح
println("Has Laptop? ${priceMap.containsKey("Laptop")}")
println("Has value 79.99? ${priceMap.containsValue(79.99)}")

// تحويل Map.entries
val sortedByValue = priceMap.entries.sortedBy { it.value }
println("Sorted by value: $sortedByValue")

**المخرجات:

TEXT 📖 للعرض فقط
Set: [PENDING, CONFIRMED, CANCELLED]
Size: 3
Map: {Laptop=1299.99, Mouse=29.99, Keyboard=79.99}
Laptop price: $1299.99 USD
Updated: {Laptop=1299.99, Mouse=24.99, Keyboard=79.99, Monitor=499.99}
Has Laptop? true
Has value 79.99? true
Sorted by value: [Mouse=24.99, Keyboard=79.99, Monitor=499.99, Laptop=1299.99]

▶ مثال: groupBy و partition

KOTLIN
val items = listOf(
    "apple" to 1.20,
    "banana" to 0.50,
    "apple" to 1.30,
    "kiwi" to 2.00,
    "banana" to 0.45,
    "apple" to 1.25
)

// groupBy - تجميع حسب مفتاح
val byName = items.groupBy { it.first }
println("Apples: ${byName["apple"]?.size}")
println("Bananas: ${byName["banana"]?.size}")

// تجميع مع عملية
val sumByName = items.groupBy(
    { it.first },
    { it.second }
).mapValues { (_, prices) -> prices.sum() }
println("Total prices: $sumByName")

// partition - تقسيم حسب شرط
val (cheap, expensive) = items.partition { it.second < 1.0 }
println("Cheap: ${cheap.size}, Expensive: ${expensive.size}")

// associateBy - قائمة إلى Map
val byKey = items.associateBy { it.first }
println("First banana: ${byKey["banana"]}")

**المخرجات:

TEXT 📖 للعرض فقط
Apples: 3
Bananas: 2
Total prices: {apple=3.75, banana=0.95, kiwi=2.0}
Cheap: 2, Expensive: 4
First banana: (banana, 0.45)

▶ مثال: Sequence للأداء

KOTLIN
// مع List - تنفيذ متزامن (immediate)
val listResult = listOf(1, 2, 3, 4, 5)
    .map { it * 2 }       // يطبق على كل العناصر فوراً
    .filter { it > 4 }     // يطبق على كل العناصر
    .take(2)               // يأخذ أول 2
    .toList()
println("List: $listResult")

// مع Sequence - تنفيذ كسول
val seqResult = sequenceOf(1, 2, 3, 4, 5)
    .map { it * 2 }
    .filter { it > 4 }
    .take(2)
    .toList()
println("Sequence: $seqResult")

// مثال عملي: معالجة مليون عنصر
val largeList = (1..1_000_000).toList()

// List: O(n) في كل خطوة
val listTime = measureTime {
    largeList
        .map { it * 2 }
        .filter { it > 1_000_000 }
        .take(10)
        .toList()
}
println("List time: ${listTime}ms")

// Sequence: يوقف عند take(10)
val seqTime = measureTime {
    largeList.asSequence()
        .map { it * 2 }
        .filter { it > 1_000_000 }
        .take(10)
        .toList()
}
println("Sequence time: ${seqTime}ms")

**المخرجات:

TEXT 📖 للعرض فقط
List: [6, 8]
Sequence: [6, 8]
List time: Xms
Sequence time: Yms

▶ مثال: groupBy و aggregate

KOTLIN
data class Sale(val product: String, val amount: Double, val month: String)

val sales = listOf(
    Sale("Laptop", 1299.99, "Jan"),
    Sale("Mouse", 29.99, "Jan"),
    Sale("Laptop", 1499.99, "Feb"),
    Sale("Mouse", 24.99, "Feb"),
    Sale("Keyboard", 79.99, "Feb"),
    Sale("Laptop", 1199.99, "Mar")
)

// تجميع حسب المنتج
val byProduct = sales.groupBy(
    { it.product },
    { it.amount }
).mapValues { (_, amounts) -> amounts.sum() }
println("Revenue by product: $byProduct")

// تجميع متعدد المستويات
val byProductMonth = sales.groupBy { it.product }
    .mapValues { (_, sales) ->
        sales.groupBy(
            { it.month },
            { it.amount }
        ).mapValues { (_, amounts) -> amounts.sum() }
    }
println("Revenue by product & month: $byProductMonth")

// count مع شرط
val laptopSales = sales.count { it.product == "Laptop" }
println("Laptop sales count: $laptopSales")

// sumOf مع selector
val totalJan = sales.sumOf { if (it.month == "Jan") it.amount else 0.0 }
println("January total: \$$totalJan USD")

**المخرجات:

TEXT 📖 للعرض فقط
Revenue by product: {Laptop=3999.97, Mouse=54.98, Keyboard=79.99}
Revenue by product & month: {Laptop={Jan=1299.99, Feb=1499.99, Mar=1199.99}, Mouse={Jan=29.99, Feb=24.99}, Keyboard={Feb=79.99}}
Laptop sales count: 3
January total: $1329.98 USD

▶ مثال: zip و flatten

KOTLIN
val names = listOf("Alice", "Bob", "Charlie")
val ages = listOf(30, 25, 35)
val cities = listOf("NYC", "LA", "Chicago")

// zip - دمج قائمتين
val nameAgePairs = names.zip(ages)
println("Pairs: $nameAgePairs")

// zip مع تحويل
val profiles = names.zip(ages) { name, age -> "$name ($age)" }
println("Profiles: $profiles")

// zip ثلاث قوائم
val triples = names.zip(ages).zip(cities) { (n, a), c -> Triple(n, a, c) }
println("Triples: $triples")

// flatten قائمة من القوائم
val nested = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))
val flat = nested.flatten()
println("Flattened: $flat")

// flatMap
val words = listOf("Hello", "World")
val chars = words.flatMap { it.toList() }
println("Chars: $chars")

**المخرجات:

TEXT 📖 للعرض فقط
Pairs: [(Alice, 30), (Bob, 25), (Charlie, 35)]
Profiles: [Alice (30), Bob (25), Charlie (35)]
Triples: [(Alice, 30, NYC), (Bob, 25, LA), (Charlie, 35, Chicago)]
Flattened: [1, 2, 3, 4, 5, 6]
Chars: [H, e, l, l, o, W, o, r, l, d]

❓ أسئلة شائعة

س ما الفرق بين عمليات مجموعات كوتلن و Java Stream؟
ج عمليات مجموعات كوتلن أكثر إيجازاً (كلمة it، لامبدا خلفية)، لا حاجة لتحويلات stream()/collect()، و Sequence مشابه لـ Stream لكن أخف.
س متى يجب أن أستخدم Sequence؟
ج استخدم Sequence عندما تكون البيانات كبيرة (>10,000)، أو خطوات العملية كثيرة (3+)، أو تحتاج عمليات دائرة قصيرة (take/first). للبيانات الصغيرة، List أبسط.
س هل toList() تنسخ البيانات؟
ج نعم. toList() تنشئ قائمة جديدة — إنها نسخة دفاعية. إذا احتجت فقط عرض قراءة فقط بدون نسخ، استخدم مرجع واجهة List.
س fold أو reduce — أيهما أختار؟
ج فضّل fold لأنه يسمح بتحديد قيمة ابتدائية وآمن للمجموعات الفارغة. reduce يطرح استثناء على المجموعات الفارغة.
س هل List في كوتلن ثابتة حقاً؟
ج لا. List في كوتلن واجهة للقراءة فقط (لا يمكن تعديلها من خلالها)، لكن التطبيق الأساسي قد يكون متغيراً. الثبات الحقيقي يتطلب إنشاء نسخة بـ toList().
س هل هناك فرق بين flatMap و map + flatten؟
ج متكافئان وظيفياً؛ flatMap أكثر كفاءة (يتم في خطوة واحدة). إنه الاختصار المدمج لـ map + flatten.

📖 ملخص


📝 تمارين

  1. مبتدئ (⭐): استخدم filter و map لاستخراج معرفات الطلبات ذات المبالغ > 1000 دولار من قائمة طلبات. تلميح: orders.filter { }.map { }
  2. متوسط (⭐⭐): استخدم groupBy + mapValues لحساب إجمالي إنفاق كل عميل، مرتباً تنازلياً حسب المبلغ. تلميح: groupBy { it.customer }.mapValues { }
  3. متقدم (⭐⭐⭐): استخدم Sequence لتنفيذ خط معالجة كسول لملايين الطلبات: filter → map → take(100)، واطبع عدد العناصر المعالجة فعلياً. تلميح: استخدم عداداً في onEach

← السابق | التالي →

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%