الدوال والمصفوفات والنصوص

مقدّمة إلى المصفوفات

15 دقيقة الدرس 5 من 14

مقدّمة إلى المصفوفات

حتى الآن كل متغيّر صرّحتَ به يحمل قيمة واحدة — int واحد أو String واحد وهكذا. لكن ماذا لو احتجتَ إلى تخزين درجات ثلاثين طالبًا، أو أسماء أيام الأسبوع؟ إنشاء ثلاثين متغيّرًا منفصلًا أمرٌ مرهق وغير عملي. تحلّ المصفوفات هذه المشكلة بتجميع قيم متعدّدة من النوع ذاته تحت اسم واحد.

ما هي المصفوفة؟

المصفوفة هي مجموعة مُرتَّبة ذات حجم ثابت تحتوي على قيم تشترك جميعها في النوع نفسه. تخيّلها كصفٍّ من الصناديق المرقّمة: كل صندوق يحمل قيمة واحدة، ولكل صندوق رقم موضع يُسمّى الفهرس.

  • يجب أن يكون كل عنصر في المصفوفة من النوع ذاته (مثلاً كلّها int أو كلّها String).
  • حجم المصفوفة ثابت عند إنشائها — لا يمكنك تصغيرها أو تكبيرها لاحقًا.
  • تبدأ الفهارس من 0 وليس من 1.
الفهرسة الصفرية مُستخدَمة في جافا وأغلب لغات البرمجة. مصفوفة تحتوي على 5 عناصر لها فهارس صالحة هي 0 و1 و2 و3 و4. الفهرس 5 غير موجود.

التصريح عن مصفوفة

يُوضَع قوسا الفهرسة إما بعد النوع أو بعد اسم المتغيّر. الأسلوب المعتاد في جافا هو وضعهما بعد النوع:

// الأسلوب المفضّل int[] scores; // صحيح أيضًا لكن أقل شيوعًا int scores[];

التصريح وحده لا يُنشئ المصفوفة بعد — بل يحجز اسمًا سيُشير إلى مصفوفة عند إنشائها.

تهيئة المصفوفة

ثمّة طريقتان شائعتان لمنح المصفوفة قيمها.

1. التخصيص بـ new ثم الإسناد عنصرًا بعنصر

استخدم new int[5] لإنشاء مصفوفة تستوعب 5 أعداد صحيحة تمامًا. تملأ جافا جميع الخانات بالقيمة الافتراضية للنوع — 0 للأنواع العددية، وfalse لـ boolean، وnull للكائنات.

int[] scores = new int[5]; // خمس خانات، جميعها مُهيَّأة بـ 0 scores[0] = 95; scores[1] = 87; scores[2] = 76; scores[3] = 91; scores[4] = 68; System.out.println(scores[2]); // يطبع 76

2. مُهيِّئ المصفوفة (التصريح والتعبئة دفعةً واحدة)

إذا كنتَ تعرف القيم مسبقًا، يمكنك توفيرها داخل قوسين معكوفين. تحسب جافا عددها وتضبط الحجم تلقائيًا.

int[] scores = {95, 87, 76, 91, 68}; String[] days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
استخدم صيغة المُهيِّئ كلّما كانت جميع القيم معروفة وقت الترجمة — فهي أقصر وأقل عُرضةً للأخطاء من إنشاء مصفوفة فارغة ثم ملئها يدويًا.

قراءة طول المصفوفة

تكشف كل مصفوفة عن حقل length (وليس تابعًا — لا أقواس) يُعيد عدد الخانات التي أُنشئت بها:

int[] scores = {95, 87, 76, 91, 68}; System.out.println(scores.length); // يطبع 5

يعكس length دائمًا سعة المصفوفة لا عدد العناصر غير الصفرية أو غير الـ null. مصفوفة أُنشئت بـ new int[10] يساوي length فيها 10 دائمًا حتى لو ملأتَ ثلاث خانات فقط.

الوصول إلى العناصر وتعديلها

اقرأ أي عنصر أو عدّله باستخدام فهرسه بين قوسين معكوفين:

String[] days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; // قراءة System.out.println(days[0]); // Monday System.out.println(days[4]); // Friday // تعديل days[2] = "WEDNESDAY"; System.out.println(days[2]); // WEDNESDAY

استثناء ArrayIndexOutOfBoundsException

أكثر أخطاء المصفوفات شيوعًا هو استخدام فهرس غير موجود — سواء أكان سالبًا أم مساويًا لطول المصفوفة أم أكبر منه. تُلقي جافا في هذه الحالة استثناء ArrayIndexOutOfBoundsException وقت التشغيل ويتوقّف البرنامج ما لم تعالج الاستثناء.

int[] numbers = {10, 20, 30}; // الفهارس الصالحة: 0 و1 و2 System.out.println(numbers[3]); // عطل: ArrayIndexOutOfBoundsException System.out.println(numbers[-1]); // عطل: ArrayIndexOutOfBoundsException
الخطأ بمقدار واحد هو السبب الكلاسيكي. إذا احتوت المصفوفة على n عنصرًا فالفهرس الأخير الصالح هو n - 1. الوصول إلى array[array.length] يكون دائمًا خارج الحدود. في حالة الشك، قارن فهرسك بـ array.length - 1.

النمط الآمن هو استخدام length دائمًا عند حساب الفهرس الأخير بدلًا من رقم ثابت مُضمَّن:

int[] scores = {95, 87, 76, 91, 68}; // آمن: يُشير دائمًا إلى العنصر الأخير System.out.println(scores[scores.length - 1]); // يطبع 68

مثال متكامل

يجمع المقطع التالي كل ما تعلّمناه: التصريح والتهيئة وقراءة الطول والوصول إلى العناصر وتحديث قيمة.

public class ArrayDemo { public static void main(String[] args) { // التصريح والتهيئة int[] temperatures = {22, 25, 19, 30, 28}; // قراءة الطول System.out.println("Days recorded: " + temperatures.length); // 5 // الوصول الآمن إلى العنصر الأول والأخير System.out.println("First day: " + temperatures[0]); // 22 System.out.println("Last day: " + temperatures[temperatures.length - 1]); // 28 // تعديل عنصر temperatures[2] = 21; System.out.println("Updated third day: " + temperatures[2]); // 21 } }

الخلاصة

تتيح لك المصفوفات تخزين قيم متعدّدة من النوع ذاته تحت اسم واحد. صرّح عنها بـ type[]، وأنشئها بـ new type[size] أو بمُهيِّئ، وصِل إلى عناصرها بفهرس يبدأ من الصفر. استخدم .length لمعرفة الحجم، واحرص دائمًا على أن تبقى فهارسك بين 0 وlength - 1 لتجنّب استثناء ArrayIndexOutOfBoundsException. الدرس التالي يبني على هذا الأساس ويريك كيف تُكرّر على عناصر المصفوفة وتُجري عليها عمليات شائعة.