JavaRush /مدونة جافا /Random-AR /Java ArrayList في الصور

Java ArrayList في الصور

نشرت في المجموعة
مرحبًا! محاضرة اليوم ArrayListستكون من ناحية أبسط، ومن ناحية أخرى أصعب من المحاضرات السابقة. قائمة المصفوفات العاملة بالصور - 1الأمر أكثر صعوبة، لأننا سننظر اليوم "تحت الغطاء" ArrayListوندرس ما يحدث له أثناء العمليات. من ناحية أخرى، لن يكون هناك أي كود تقريبًا في هذه المحاضرة - معظمها صور وشروحات. لذلك، دعنا نذهب :) كما تعلم بالفعل، ArrayListيوجد داخل "a" مصفوفة عادية تعمل كمخزن بيانات. في معظم الحالات، لا نحدد الحجم الدقيق للقائمة. لكن المصفوفة الداخلية يجب أن يكون لها حجم معين! هذا صحيح. حجمه الافتراضي هو [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);//добавляем ford в ячейку 1, которая уже занята
}
مرة أخرى، يقوم أولاً بالتحقق مما إذا كانت هناك مساحة كافية في المصفوفة. إذا كانت هناك مساحة كافية، يتم نقل العناصر إلى اليمين بدءًا من الخلية التي نقوم بإدراج العنصر الجديد فيها. نلصق في الخلية التي تحتوي على الفهرس 1. أي أنه يتم نسخ العنصر من الخلية 3 إلى الخلية 4، والعنصر 2 إلى الخلية 3، والعنصر 1 إلى الخلية 2. قائمة المصفوفات العاملة بالصور - 4وبعد ذلك، يتم لصق العنصر الجديد في مكانه. bugattiتم بالفعل نسخ العنصر السابق ( ) من هناك إلى موقع جديد. قائمة المصفوفات العاملة بالصور - 5الآن دعونا نتعرف على كيفية حدوث هذه العملية إذا لم تكن هناك مساحة للإدراج في المصفوفة. قائمة المصفوفات العاملة بالصور - 6أولاً، بالطبع، يتم إجراء فحص لمعرفة ما إذا كانت هناك مساحة كافية. إذا اتضح أنه لا توجد مساحة كافية، ArrayListفسيتم إنشاء مصفوفة جديدة بالحجم (حجم OldArray * 1.5) + 1 داخل "a. في حالتنا، سيكون حجم المصفوفة الجديدة 16 خلية. سيتم نسخ كافة العناصر الحالية هناك على الفور. عمل ArrayList بالصور - 7سيتم حذف المصفوفة القديمة بواسطة جامع البيانات المهملة، وسيبقى المصفوفة الجديدة الموسعة فقط. الآن هناك مساحة حرة للعنصر الجديد. نلصقه في الخلية رقم 3 المشغولة. الآن يبدأ الإجراء المألوف. يتم نقل كافة العناصر التي تبدأ من الفهرس 3 خلية واحدة إلى اليمين، ويتم إضافة عنصر جديد بهدوء. قائمة المصفوفات العاملة بالصور - 8والآن تم الإدراج بنجاح! لقد قمنا بفرز الإدراج. الآن دعونا نتحدث عن إزالة العناصر . كما تتذكر، عند العمل مع المصفوفات، واجهنا مشكلة: عندما قمنا بحذفها، ظلت "الثقوب" فيها. كان الحل الوحيد هو نقل العناصر إلى اليسار في كل مرة يتم حذفها، وكان عليك كتابة رمز النقل بنفسك. ArrayListيعمل على نفس المبدأ، ولكن يتم تنفيذ هذه الآلية فيه بالفعل تلقائيا. قائمة المصفوفات العاملة بالصور - 9وهذا ما يبدو عليه الأمر: قائمة المصفوفات العاملة بالصور - 10وفي النهاية حصلنا على النتيجة المرجوة: تم حذف قائمة المصفوفات العاملة بالصور - 11العنصر lamboبنجاح. هنا قمنا بالإزالة من المنتصف. ومن الواضح أن الحذف من نهاية القائمة سيكون أسرع، حيث تتم إزالة العنصر المطلوب دون تغيير جميع العناصر الأخرى. دعونا نلقي نظرة أخرى على حجم المصفوفة الداخلية وتخزينها في الذاكرة. توسيع المصفوفة هو عملية تتطلب قدرًا معينًا من الموارد. لذلك، لا ينبغي عليك الإنشاء ArrayListبالحجم الافتراضي إذا كنت تعرف على وجه اليقين أنه سيحتوي على 100 عنصر على الأقل. بحلول الوقت الذي تقوم فيه بإدراج العنصر رقم 100، ستتوسع المصفوفة الداخلية 6 مرات ، مع نقل جميع العناصر في كل مرة.
  • من 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 عنصرًا، وهي مملوءة بالكامل: قائمة المصفوفات العاملة بالصور - 13أثناء تشغيل البرنامج، نزيل منها 77 عنصرًا، ويبقى فيها 11 عنصرًا فقط: هل قائمة المصفوفات العاملة بالصور - 14خمنت بالفعل ما هي المشكلة؟ الاستخدام غير الفعال للذاكرة، بطبيعة الحال! نحن نستخدم 11 خلية فقط، بينما لدينا ذاكرة مخصصة لـ 88 عنصرًا - وهذا أكثر بثمانية أضعاف مما نحتاجه! لتنفيذ التحسين في هذه الحالة، يمكنك استخدام طريقة فئة خاصة ArrayList- trimToSize(). إنه "يقطع" طول المصفوفة الداخلية إلى عدد العناصر المخزنة فيها حاليًا. قائمة المصفوفات العاملة بالصور - 15الآن يتم تخصيص أكبر قدر من الذاكرة حسب الحاجة! :)
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION