كيف تتوقف عن كتابة Stream.collect في Kotlin وتبدأ في العيش
هل سبق لك أن انتقلت من Java إلى Kotlin وشعرت وكأنك سمكة أُلقيت على الشاطئ؟ خاصة عندما يتعلق الأمر بالـ Streams. في Java 8، اعتدنا على سلاسل .stream().filter().map().collect(). وفي Kotlin - فجأة! - لا يوجد Stream.collect بالشكل المألوف. لكن لا تتسرع في الذعر. في الواقع، في مكتبة Kotlin القياسية يوجد كل ما هو نفسه، لكنه أكثر ملاءمة وإيجازاً وبدون ضوضاء زائدة.
في هذه المقالة، سنشرح ما هي المكافئات لـ Java 8 Stream.collect الموجودة في Kotlin، وسنعرض ذلك بأمثلة حقيقية. إذا كنت تبحث عن إجابة لسؤال "ما هي مكافئات Java 8 Stream.collect المتوفرة في مكتبة Kotlin القياسية؟" - فأنت في المكان الصحيح. سنستعرض أشهر العمليات: من التجميع البسيط في قائمة إلى التجميع المعقد ودمج السلاسل النصية.
هل أنت مستعد؟ لنبدأ!
1. أبسط حالة: toList() و toSet()
في Java، لتجميع نتيجة Stream في قائمة، تكتب:
List<String> result = list.stream() .filter(s -> s.length() > 3) .collect(Collectors.toList());في Kotlin، يتحول هذا إلى سطر واحد بدون collect:
val result = list.filter { it.length > 3 }نعم، لم تسمع خطأ. filter في Kotlin يعيد قائمة بالفعل. لكن إذا كنت بحاجة إلى تحديد نوع المجموعة بشكل صريح، استخدم toList() أو toSet() أو toMutableList():
val numbers = listOf(1, 2, 3, 4, 5, 5)val uniqueNumbers: Set<Int> = numbers.toSet()// النتيجة: [1, 2, 3, 4, 5]الخلاصة: في Kotlin، معظم عمليات المجموعات (filter، map، flatMap) تعيد قائمة فوراً. لم تعد بحاجة إلى collect(Collectors.toList()).
2. التجميع: groupingBy بدلاً من Collectors.groupingBy
التجميع هو أحد أكثر المهام شيوعاً. في Java يبدو كالتالي:
Map<Integer, List<String>> byLength = list.stream() .collect(Collectors.groupingBy(String::length));في Kotlin، توجد دالة أنيقة groupBy:
val words = listOf("قط", "رمز", "مرجل", "قطة صغيرة")val byLength = words.groupBy { it.length }// النتيجة: {3=[قط, رمز], 5=[مرجل], 4=[قطة صغيرة]}لكن هناك فارق بسيط: groupBy يعيد فوراً Map<K, List<V>>. وماذا لو كنت بحاجة إلى شيء أكثر تعقيداً، مثل حساب عدد العناصر في كل مجموعة؟ في Java كنت ستستخدم Collectors.counting():
Map<Integer, Long> countByLength = list.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting()));في Kotlin، لهذا يوجد groupingBy + eachCount:
val countByLength = words.groupingBy { it.length }.eachCount()// النتيجة: {3=2, 5=1, 4=1}وإذا كنت بحاجة إلى تجميع ليس في قائمة، بل في مجموعة مثلاً؟ استخدم groupBy مع التحويل:
val byLengthSet = words.groupBy(keySelector = { it.length }, valueTransform = { it.uppercase() })// النتيجة: {3=[قط, رمز], 5=[مرجل], 4=[قطة صغيرة]}نصيحة: إذا كنت بحاجة إلى شيء بين groupBy و groupingBy، استخدم groupingBy - فهو كسول ويسمح بتطبيق تجميعات مختلفة (eachCount، fold، reduce).
3. دمج السلاسل النصية: joinToString() بدلاً من Collectors.joining()
في Java، دمج السلاسل النصية بفاصل:
String joined = list.stream() .collect(Collectors.joining(", "));في Kotlin، يتم ذلك بشكل أسهل:
val words = listOf("Kotlin", "Java", "Python")val joined = words.joinToString(",