Kotlin: List vs Array — ما المكمن؟
\n\nإذا كنت تكتب بلغة Kotlin لمدة أسبوع على الأقل، فمن المحتمل أنك واجهت السؤال: "لماذا لا يمكنني ببساطة استخدام Array في كل مكان؟ لماذا أحتاج إلى List و MutableList؟"
هذا السؤال هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. وليس من دون سبب. للوهلة الأولى، كل من القائمة والمصفوفة تخزنان العناصر، ويمكن الوصول إليها عن طريق الفهرس، ويمكن التكرار عليها. ولكن إذا تعمقت أكثر، ستكتشف اختلافات جوهرية تؤثر على الأداء، وأمان الكود، وحتى على طريقة تفكيرك عند تصميم البنية.
\n\nفي هذا البرنامج التعليمي، سنقوم بتحليل الفرق بين List و Array في Kotlin بالتفصيل. ستتعرف على متى تستخدم المصفوفة ومتى تستخدم القائمة، ولماذا يختار المطورون ذوو الخبرة دائمًا تقريبًا List.
1. الأساسيات: ما هي Array في Kotlin؟
\n\nArray في Kotlin هي إسقاط مباشر لمصفوفة Java. وهي تسلسل ثابت من العناصر من نفس النوع. عندما تقوم بإنشاء مصفوفة، فإنك تخصص لها ذاكرة فورًا. لا يمكن تغيير حجم المصفوفة بعد إنشائها.
// إنشاء مصفوفة\nval numbers: Array<Int> = arrayOf(1, 2, 3, 4, 5)\nprintln(numbers[0]) // 1\nnumbers[2] = 10 // يمكن تغيير القيمة\nprintln(numbers[2]) // 10\n\nالمصفوفات في Kotlin هي mutable (قابلة للتغيير) بطبيعتها: يمكنك دائمًا استبدال عنصر في فهرس معين. لكن لا يمكنك إضافة عنصر جديد أو حذف عنصر موجود. الحجم ثابت إلى الأبد.
\n\nخصائص Array:
\n- \n
- حجم ثابت — لا يمكن إضافة أو حذف عنصر. \n
- محتوى قابل للتغيير — يمكن إعادة كتابة العناصر. \n
- الأداء — أقصى أداء، لأنه وصول مباشر إلى الذاكرة. \n
- المصفوفات البدائية — هناك أنواع خاصة:
IntArray،ByteArray،FloatArray، إلخ. تعمل بدون تغليف (boxing)، مما يعطي زيادة في السرعة. \n
// مصفوفة بدائية — بدون boxing\nval intArray: IntArray = intArrayOf(1, 2, 3, 4, 5)\n\n2. الأساسيات: ما هي List في Kotlin؟
\n\nList هي واجهة من المكتبة القياسية لـ Kotlin. على عكس المصفوفة، القائمة هي تجريد. أنت لا تعرف بالضبط كيف تخزن البيانات داخليًا (قد تكون ArrayList، LinkedList أو شيء آخر).
// إنشاء قائمة غير قابلة للتغيير\nval fruits: List<String> = listOf("apple", "banana", "cherry")\nprintln(fruits[0]) // apple\n// fruits[0] = "orange" // خطأ في الترجمة!\n\nالميزة الرئيسية في Kotlin هي التقسيم إلى read-only (للقراءة فقط) (List) و mutable (قابلة للتغيير) (MutableList).
List (للقراءة فقط):
\n- \n
- لا يمكن تغيير المحتوى (لا إضافة ولا حذف ولا استبدال). \n
- يمكن القراءة فقط. \n
- أكثر أمانًا لنقل البيانات بين المكونات. \n
MutableList:
\n- \n
- يمكن إضافة وحذف واستبدال العناصر. \n
- حجم ديناميكي. \n
- في الممارسة العملية، غالبًا ما يتم استخدام
ArrayListتحت الغطاء. \n
val mutableFruits: MutableList<String> = mutableListOf("apple", "banana")\nmutableFruits.add("orange") // OK\nmutableFruits.remove("banana") // OK\nmutableFruits[0] = "pear" // OK\n\n3. الاختلافات الرئيسية بين List vs Array
\n\nدعنا نلخص كل شيء في جدول توضيحي (في الكود — في شكل تعليقات).
\n\n// 1. قابلية التغيير\nval array = arrayOf(1, 2, 3)\narray[0] = 99 // ✅ يعمل\n\nval list = listOf(1, 2, 3)\n// list[0] = 99 // ❌ خطأ في الترجمة\n\nval mutableList = mutableListOf(1, 2, 3)\nmutableList[0] = 99 // ✅ يعمل\n\n// 2. الحجم\nval fixedArray = arrayOf(1, 2, 3)\n// fixedArray.add(4) // ❌ لا توجد هذه الدالة\n// va