CodeGym /مدونة جافا /Random-AR /قائمة المصفوفات في الصور
John Squirrels
مستوى
San Francisco

قائمة المصفوفات في الصور

نشرت في المجموعة
أهلاً! درس اليوم ArrayListسيكون أسهل وأصعب من الدروس السابقة.
قائمة المصفوفات في الصور - 1
سيكون الأمر أكثر صعوبة لأننا سننظر اليوم تحت الغطاء ArrayListوندرس ما يحدث أثناء العمليات المختلفة. ومن ناحية أخرى، لن يحتوي هذا الدرس على أي كود تقريبًا. إنها في الغالب صور وشروحات. حسنًا، دعنا نذهب :) كما تعلم بالفعل، ArrayListيحتوي على مصفوفة عادية بداخله، والتي تعمل كمخزن بيانات. في معظم الحالات، لا نحدد الحجم الدقيق للقائمة. لكن المصفوفة الداخلية يجب أن يكون لها حجم معين! وهكذا يحدث. حجمه الافتراضي هو 10 .
public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
}
قائمة المصفوفات في الصور - 2 أولاً، دعونا نرى كيف تبدو إضافة عناصر جديدة. أول أمر عمل هو التحقق مما إذا كانت المصفوفة الداخلية بها مساحة كافية في المصفوفة الداخلية وما إذا كان هناك عنصر آخر مناسب. إذا كان هناك مساحة، فسيتم إضافة العنصر الجديد إلى نهاية القائمة. عندما نقول "حتى النهاية"، فإننا لا نعني الموضع الأخير في المصفوفة (سيكون ذلك غريبًا). ونعني الموضع الذي يلي العنصر الحالي الأخير. سيكون مؤشره cars.size(). قائمتنا فارغة حاليا ( cars.size() == 0). وبناء على ذلك، سيتم إضافة العنصر الجديد في الموضع 0.
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
قائمة المصفوفات في الصور - 3 هذا واضح بما فيه الكفاية. ماذا يحدث إذا أدخلنا في المنتصف، أي بين العناصر الأخرى؟
public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
   Car ferrari = new Car("Ferrari 360 Spider");
   Car bugatti = new Car("Bugatti Veyron");
   Car lambo = new Car("Lamborghini Diablo");
   Car ford = new Car("Ford Modneo");

   cars.add(ferrari);
   cars.add(bugatti);
   cars.add(lambo);

   cars.add(1, ford);// add ford to cell 1, which is already occupied
}
مرة أخرى، يجب أولاً التحقق من وجود مساحة كافية في المصفوفة. إذا كان هناك مساحة كافية، فسيتم إزاحة العناصر إلى اليمين ، بدءًا من الموضع الذي نقوم بإدراج العنصر الجديد فيه. نحن نقوم بالإدراج في الموضع 1. وبعبارة أخرى، يتم نسخ العنصر من الموضع 3 إلى الموضع 4، والعنصر 2 إلى الموضع 3، والعنصر 1 إلى الموضع 2. قائمة المصفوفات في الصور - 4 ثم يتم إدراج العنصر الجديد في مكانه. تم بالفعل نسخ العنصر السابق (بوغاتي) من هناك إلى موضع جديد. قائمة المصفوفات في الصور - 5 الآن دعونا نلقي نظرة على كيفية حدوث هذه العملية إذا لم يكن هناك أماكن لإدراج عناصر جديدة في المصفوفة. قائمة المصفوفات في الصور - 6 وبطبيعة الحال، هناك أولا التحقق لمعرفة ما إذا كان هناك مساحة كافية. إذا لم تكن هناك مساحة كافية، فسيتم إنشاء مصفوفة جديدة داخل المصفوفة ArrayListالتي حجمها هو حجم المصفوفة القديمة مضروبة بـ 1.5 زائد 1. في حالتنا، سيكون حجم المصفوفة الجديدة 16. سيتم نسخ جميع العناصر الحالية إلى هناك في الحال. قائمة المصفوفات في الصور - 7 سيتم حذف المصفوفة القديمة بواسطة جامع البيانات المهملة، وسيبقى المصفوفة الجديدة الموسعة فقط. الآن هناك مجال لعنصر جديد. نحن نقوم بإدخاله في الموضع 3، وهو مشغول. الآن يبدأ الإجراء المألوف. يتم نقل جميع العناصر، بدءًا من الفهرس 3، موضعًا واحدًا إلى اليمين، ويتم إضافة العنصر الجديد بهدوء. قائمة المصفوفات في الصور - 8 ويتم الإدراج! وانتهينا من الإدراج. الآن دعونا نتحدث عن إزالة العناصر . ستتذكر أننا واجهنا مشكلة عند العمل مع المصفوفات: إزالة العناصر تؤدي إلى حدوث "ثقوب" في المصفوفة. وكان السبيل الوحيد للخروج هو نقل العناصر المتبقية مع كل عملية إزالة، وكان علينا كتابة التعليمات البرمجية الخاصة بنا في كل مرة لإجراء هذا النقل. تتبع ArrayList نفس المبدأ، لكنها تطبق هذه الآلية بالفعل. قائمة المصفوفات في الصور - 9 هكذا يبدو الأمر: قائمة المصفوفات في الصور - 10 وفي النهاية نحصل على ما نريد: تمت إزالة العنصر قائمة المصفوفات في الصور - 11 . lamboهنا قمنا بإزالة عنصر من المنتصف. من الواضح أن إزالة عنصر من نهاية القائمة تكون أسرع، حيث تتم إزالة العنصر ببساطة دون الحاجة إلى نقل جميع العناصر الأخرى. لنتحدث مرة أخرى للحظة عن أبعاد المصفوفة الداخلية وكيفية ترتيبها في الذاكرة. يتطلب توسيع المصفوفة بعض الموارد. وبناءً على ذلك، لا تقم بإنشاء ملف ArrayListبالحجم الافتراضي إذا كنت متأكدًا من أنه سيحتوي على 100 عنصر على الأقل. يجب توسيع المصفوفة الداخلية 6 مرات بحلول الوقت الذي تقوم فيه بإدراج العنصر رقم 100، ويجب تغيير جميع العناصر في كل مرة.
  • من 10 عناصر إلى 16
  • من 16 عنصرًا إلى 25 عنصرًا
  • من 25 إلى 38
  • من 38 إلى 58
  • من 58 إلى 88
  • من 88 إلى 133 (أي حجم المصفوفة القديمة مضروبًا في 1.5 زائد 1)
كما يمكنك أن تتخيل، فإن هذا يتطلب الكثير من الموارد. لذا، إذا كنت تعرف بالفعل (ولو تقريبًا) العدد المطلوب من العناصر، فمن الأفضل إنشاء قائمة بمصفوفة ذات حجم معين:
ArrayList<Car> cars = new ArrayList<>(100);
الآن سيتم تخصيص الذاكرة لمصفوفة مكونة من 100 عنصر دفعة واحدة، مما يجعل المصفوفة أكثر كفاءة (لن تحتاج إلى توسيع). هذه الاستراتيجية أيضا لها جانب آخر. عند إزالة كائنات من ArrayList، لا يقل حجم المصفوفة الداخلية تلقائيًا. لنفترض أن لدينا ArrayListمصفوفة داخلية كاملة مكونة من 88 عنصرًا: قائمة المصفوفات في الصور - 12 أثناء تشغيل البرنامج، نزيل 77 عنصرًا، ويتبقى 11 عنصرًا فقط: قائمة المصفوفات في الصور - 13 هل خمنت بالفعل ما هي المشكلة؟ لقد فهمت، الاستخدام غير الفعال للذاكرة! نحن نستخدم هنا 11 موضعًا فقط، لكننا خصصنا ذاكرة لـ 88 عنصرًا. هذا 8 مرات أكثر مما نحتاجه! في هذه الحالة، يمكننا تحسين استخدام ذاكرتنا باستخدام إحدى ArrayListالطرق الخاصة للفصل: trimToSize(). تعمل هذه الطريقة على "قص" طول المصفوفة الداخلية بما يتناسب مع عدد العناصر المخزنة فيها حاليًا. قائمة المصفوفات في الصور - 14 لقد خصصنا الآن القدر الذي نحتاجه من الذاكرة فقط! :)
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION