مجموعة من الكائنات في Java

⚡ ملخص ذكي

مجموعة من الكائنات في Java يخزن مراجع الكائنات في خانة متجاورة ذات حجم ثابت، مما يسمح لمتغير واحد باحتواء العديد من مثيلات الفئة والوصول إلى كل منها من خلال فهرس للتكرار والتغيير والتمرير إلى الطرق.

  • 📦 التخزين المرجعي: كل خانة في Java تحتوي مصفوفة الكائنات على مرجع إلى كائن، وليس الكائن نفسه، على غرار أي متغير كائن في Java.
  • 🧱 عملية إنشاء من خطوتين: قم بتخصيص المصفوفة باستخدام new ClassName[size]، ثم قم بتخصيص كل كائن باستخدام new ClassName() قبل استدعاء الطرق عليه.
  • ⚠️ استثناء المؤشر الفارغ: كل خانة تبدأ بقيمة فارغة. استدعاء دالة على خانة غير مهيأة يؤدي إلى ظهور استثناء NullPointerException أثناء وقت التشغيل.
  • 🔁 تكرار: استخدم حلقة for مع طول المصفوفة أو حلقة for محسّنة للتنقل بين كل عنصر في المصفوفة.
  • 📏 الحجم الثابت: لا يمكن للمصفوفة أن تنمو بعد تخصيصها. استخدم ArrayList عندما يتغير عدد العناصر أثناء التشغيل.
  • ؟؟؟؟ ️ تهيئة المُنشئ: تُتيح الدوال البانية التي يتم تمريرها أثناء الإنشاء إعدادًا أقصر وأكثر أمانًا من استدعاءات المُعدِّل اللاحقة.
  • 🚚 معلمات الطريقة: يؤدي تمرير المصفوفة إلى دالة إلى نقل مرجع، وبالتالي تكون التغييرات داخل الدالة مرئية للمستدعي.

مجموعة من الكائنات في Java

ما هي مصفوفة الكائنات في Java?

A Java مجموعة من الأشياء يخزن هذا النوع من المصفوفات عدة نسخ من نفس الفئة في حاوية واحدة ذات حجم ثابت. على عكس المصفوفة الأولية التي تخزن قيمًا مثل int, double أو boolean مباشرة في كل خانة، يتم تخزين مصفوفة من الكائنات المراجعيشير كل خانة إلى موقع الذاكرة الخاص بكائن ما، ويوجد الكائن نفسه في Java كومة.

يتطابق هذا التصميم مع كيفية تطابق أي كائن متغير in Java يعمل هذا الأسلوب. ببساطة، تجمع المصفوفة عدة مراجع للكائنات معًا لتتمكن من الوصول إليها باستخدام الفهرس. وهو الخيار الأمثل عندما يكون عدد الكائنات معروفًا مسبقًا ولا يتغير خلال فترة تشغيل البرنامج.

بناء الجملة

ClassName[] obj = new ClassName[array_length];

يُخصص الجانب الأيمن مساحة لـ array_length المراجع، جميعها مهيأة إلى nullلا يوجد أي غرض من ClassName لا يوجد حتى الآن سوى الحاوية التي يمكنها الاحتفاظ بمراجع لمثل هذه الكائنات.

كيفية إنشاء مصفوفة من الكائنات في Java

يتطلب إنشاء مصفوفة عمل من الكائنات دائمًا خطوتين لتخصيص الذاكرة. الأولى تُخصص حاوية المراجع، والثانية تُخصص كل كائن ستشير إليه الحاوية. تخطيping الخطوة الثانية هي المصدر الأكثر شيوعاً لـ NullPointerException للمبتدئين Java رمز.

الخطوة 1) فتح الخاص محرر الكود وانسخ الكود التالي:

class ObjectArray {
    public static void main(String args[]) {
        Account obj[] = new Account[2];
        // obj[0] = new Account();
        // obj[1] = new Account();
        obj[0].setData(1, 2);
        obj[1].setData(3, 4);
        System.out.println("For Array Element 0");
        obj[0].showData();
        System.out.println("For Array Element 1");
        obj[1].showData();
    }
}

class Account {
    int a;
    int b;

    public void setData(int c, int d) {
        a = c;
        b = d;
    }

    public void showData() {
        System.out.println("Value of a = " + a);
        System.out.println("Value of b = " + b);
    }
}

الخطوة 2) حفظ الملف ك ObjectArray.javaثم قم بتجميعه وتشغيله.

الخطوة 3) لاحظ الخطأ. حاول إصلاحه قبل المتابعة إلى الخطوة 4.

الخطوة 4) فحص الخط Account obj[] = new Account[2];يقوم بتخصيص مصفوفة من متغيرين مرجعيين من النوع Accountلكنها لا تخصص أي شيء Account الأشياء. كلا الخانتين تحتويان على nullوالاتصال obj[0].setData(...) على null يُثير المرجع خطأً NullPointerException في وقت التشغيل.

Java متغيرات مرجعية لمصفوفة من الكائنات

الخطوة 5) قم بإلغاء التعليق عن السطرين 4 و 5. هذان السطران يُنشئان حقيقيين Account الكائنات وتعيينها إلى obj[0] و obj[1]. تحتوي المصفوفة الآن على مراجع حقيقية، ويتم تشغيل الكود بسلاسة.

Java مصفوفة من الكائنات المعبأة

الإخراج:

For Array Element 0
Value of a = 1
Value of b = 2
For Array Element 1
Value of a = 3
Value of b = 4

كيفية تهيئة مصفوفة من الكائنات في Java

إضافةً إلى طريقة التهيئة القائمة على دوال التعيين الموضحة أعلاه، يمكن تهيئة مصفوفة من الكائنات بثلاث طرق أكثر وضوحًا. تُفضّل كل طريقة منها الوضوح على الإسهاب، لذا اختر الطريقة الأنسب للحالة.

  1. تهيئة الحلقة — قم بتخصيص المصفوفة، ثم انتقل إلى كل فهرس وقم بتعيين كائن جديد. هذا هو النمط القياسي للمصفوفات الكبيرة أو عندما يكون عدد الكائنات ديناميكيًا.
  2. تهيئة المُنشئ — تمرير القيم مباشرة إلى المُنشئ في وقت الإنشاء، لذلك لا حاجة إلى استدعاء مُعيِّن منفصل.
  3. تهيئة المصفوفة الحرفية — قم بالإعلان والتعبئة في عبارة واحدة باستخدام مضمنة { ... } مُهيئ، مثالي للمجموعات الثابتة الصغيرة.
class Account {
    int a, b;

    public Account(int a, int b) {   // constructor
        this.a = a;
        this.b = b;
    }
}

public class InitDemo {
    public static void main(String[] args) {

        // 1) Loop initialisation
        Account[] loopArr = new Account[3];
        for (int i = 0; i < loopArr.length; i++) {
            loopArr[i] = new Account(i, i * 10);
        }

        // 2) Constructor initialisation, one slot at a time
        Account[] ctorArr = new Account[2];
        ctorArr[0] = new Account(1, 2);
        ctorArr[1] = new Account(3, 4);

        // 3) Array literal initialisation
        Account[] litArr = {
            new Account(5, 6),
            new Account(7, 8),
            new Account(9, 10)
        };

        System.out.println("loop size   = " + loopArr.length);
        System.out.println("ctor size   = " + ctorArr.length);
        System.out.println("literal size= " + litArr.length);
    }
}

تُعد عملية تهيئة الحلقة هي الخيار الافتراضي الأكثر أمانًا لأنها تضمن عدم وجود خانة متبقية nullتُوضّح عملية تهيئة المُنشئ الغرض من كل كائن عند حاجته إلى وسائط مختلفة، كما تُحافظ المصفوفات الحرفية على اختصار الشيفرة البرمجية التجريبية الصغيرة. تجنّب مزج الأنماط داخل المصفوفة نفسها إلا إذا كان لديك سبب وجيه: فالاتساق يُسهّل اكتشاف الأخطاء.

التكرار والوصول إلى العناصر في Java مجموعة من الكائنات

بمجرد ملء مصفوفة من الكائنات، تغطي ثلاثة أنماط تقريبًا جميع احتياجات الوصول. اختر نمط الحلقة الذي يتناسب مع مستوى التحكم المطلوب في الفهرس.

كلاسيك for حلقة يتيح الوصول إلى الفهرس، وهو أمر مفيد لاستبدال العناصر، أو مقارنة العناصر المجاورة، أو تكرار نطاق فرعي.

for (int i = 0; i < obj.length; i++) {
    System.out.println("Element " + i);
    obj[i].showData();
}

تعزيز for حلقة (حلقة "for-each") تخفي الفهرس وتقرأ بشكل طبيعي أكثر عندما لا يكون الفهرس مطلوبًا:

for (Account acc : obj) {
    acc.showData();
}

تيارات (Java 8 وما بعدها) قم بتحويل المصفوفة إلى مسار بيانات، وهو أمر مفيد للتصفية والتحويل.pingأو التجميع دون كتابة حلقة تكرارية:

import java.util.Arrays;

Arrays.stream(obj)
      .filter(acc -> acc.a > 0)
      .forEach(Account::showData);

لقراءة أو تحديث عنصر واحد، استخدم الوصول المباشر إلى الفهرس، على سبيل المثال obj[1].setData(10, 20)تحقق دائمًا من الطول أولاً باستخدام obj.length لتجنب ArrayIndexOutOfBoundsExceptionعندما يكون أي مكان قابلاً للاستغلال null، احمِ الوصول بفحص القيمة الفارغة أو Optional للحفاظ على استمرار تشغيل البرنامج بدلاً من تعطلّه.

مقارنة بين مصفوفة الكائنات وقائمة الكائنات في Java

إن المصفوفة البسيطة من الكائنات سريعة ويمكن التنبؤ بها، لكن حجمها الثابت يصبح قيدًا بمجرد أن يتغير عدد الكائنات في وقت التشغيل. Javaيوفر إطار عمل المجموعات الخاص بـ ArrayList كبديل ديناميكي. يوضح الجدول أدناه متى يكون كل خيار مناسبًا.

الميزاتمجموعة من الكائناتقائمة من الكائنات
المقاسثابت عند الإنشاءيكبر ويصغر تلقائياً
إعلانAccount[] a = new Account[5];List<Account> list = new ArrayList<>();
عنصر الوصولa[i]list.get(i)
أضف عنصرًاغير مدعوم بعد الإنشاءlist.add(obj)
اكتب الأمانيتم تحديد النوع في وقت الترجمة عن طريق التصريحيتم تطبيق الأنواع العامة في وقت الترجمة
هاملتقراءات مفهرسة أسرع بشكل طفيفإضافة O(1) المستهلكة، بعض التكاليف الإضافية لكل عنصر
مفضل عندماالحجم معروف وثابتالحجم غير معروف أو يتغير أثناء التشغيل

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

الأسئلة الشائعة

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

قم بتعريف المصفوفة باستخدام `ClassName[] arr = new ClassName[size]`، ثم أنشئ كل كائن باستخدام `new ClassName()` في حلقة تكرارية أو باستخدام مصفوفة حرفية مضمنة. كلا الخطوتين ضروريتان؛ فالأولى تُخصص خانات مرجعية فقط.

لأنّ `new ClassName[size]` يُخصّص المصفوفة نفسها فقط. تبدأ كلّ خانة بقيمة فارغة (null)، لذا فإنّ استدعاء أيّ دالة على تلك الخانة يُسبّب استثناءً من نوع `NullPointerException`. يُمكن حلّ هذه المشكلة بتعيين `new ClassName()` لكلّ فهرس قبل استخدامه.

تتميز المصفوفة بحجم ثابت يُحدد عند إنشائها، بينما تتوسع قائمة المصفوفات وتتقلص تلقائيًا. توفر المصفوفات قراءة أسرع قليلاً باستخدام الفهرسة؛ بينما تُضيف قائمة المصفوفات طرقًا ملائمة للإضافة والحذف والتدفق لتطبيقات البرمجة اليومية.

استخدم حلقة for تقليدية مع arr.length عندما تحتاج إلى الفهرس، أو حلقة for-each مُحسّنة للتكرار البسيط. للتصفية أو التحويل، غلّف المصفوفة بـ Arrays.stream(arr) وقم بربط مسار المعالجة حسب الحاجة.

قم بتعريف المعامل كـ ClassName[] name، ثم قم باستدعاء الطريقة باستخدام متغير المصفوفة. Java يقوم بتمرير مرجع المصفوفة بالقيمة، لذا فإن التغييرات التي تطرأ على حقول العناصر داخل الطريقة تكون مرئية للمستدعي.

تتعرف مولدات أكواد التعلم الآلي على نمط التخصيص ذي الخطوتين، وتُكمل أسطر `new ClassName()` المفقودة التي ينساها المبتدئون. كما تقترح استخدام `ArrayList` عندما يكون حجم المجموعة المستهدفة غير معروف، مما يقلل من أخطاء `NullPointerException`.

نعم. يقوم GitHub Copilot بإنشاء تعريفات المصفوفات، وحلقات البناء، وكتل التكرار، وتحويلات ArrayList من تعليق يصف نموذج المجال. Revتم إنشاء الكود باستخدام iew للتحقق من صحة وسائط المُنشئ ومعالجة القيم الفارغة بشكل آمن قبل الاستخدام.

تلخيص هذه التدوينة بـ: