يطرح سؤال قياسي: كيفية تهيئة القائمة؟ لن يعمل الكود أدناه: سيؤدي إلى خطأ في الترجمة: ربما لم تتم تهيئة أسماء المتغيرات المحلية . تتطلب مواصفات Java تهيئة جميع المتغيرات المحلية (تلك الموجودة في المكدس) بالقيم المناسبة. هذه هي الطريقة التي يمكنك القيام بها: بدون أدنى شك، يجب تهيئة القائمة. يمكنك إما إنشاء القائمة في السطر الأول، أو يمكنك القيام بشيء أكثر ذكاءً واستخدام التهيئة البطيئة كما فعلنا في طريقة getAllNames() . في هذه الحالة، سيتم إنشاء القائمة فقط عند الضرورة - إذا لم يتم استيفاء الشروط الأولية، فلن تظهر القائمة أبدًا في الكومة. وهنا نأتي إلى السؤال الرئيسي: ما الحجم الذي يجب أن نحدده للقائمة؟ الخيار الأفضل هو إعطائه الحجم الدقيق. على سبيل المثال: في هذه الحالة، يجب إرجاع n من الأسماء بالضبط، ونتيجة لذلك، يتم إنشاء مجموعة من العناصر n . ومع ذلك، فإن القيمة الدقيقة لـ n ليست معروفة دائمًا. حتى في المثال الموضح، ماذا لو كان n=1000 وكان هناك 100 اسم فقط متاح؟ عند العمل مع المجموعات، الطريقة الأكثر شيوعًا هي استدعاء المُنشئ الافتراضي. إذا نظرت إلى كود مصدر Java (الإصدار 1.6) ، فكما ترى، يتم إنشاء قائمة مكونة من 10 عناصر بشكل افتراضي . أي أنه يمكننا استخدام المنشئ الافتراضي بأمان عندما لا نخطط لتخزين أكثر من 10 عناصر في القائمة. ماذا يحدث إذا حاولت إضافة العنصر الحادي عشر؟ حسنًا، لا شيء سيئ... ستتم إضافة العنصر بنجاح. انظر إلى الطريقة: يتم التحكم في حجم المصفوفة بواسطة طريقة ضمان السعة . يزيد الحجم بمقدار 1.5 مرة . يتم إنشاء مصفوفة جديدة ويتم نقل العناصر إليها. إذا قمنا بتعيين الحجم على 10، ففي العنصر الحادي عشر:
public List
getAllNames() { List
names; if (/*необходимые условия выполнены*/) { names = new ArrayList
(); /*заполнение списка*/ } return names; }
List
names = null; List
names = new ArrayList
(); List
names = new ArrayList
(0); List
names = new ArrayList
(size);
public List
getTopNames (int n) { List
names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList
(n); /*заполнение списка*/ } return names; }
names = new ArrayList
();
/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; }
public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
- يتغير الحجم إلى 10 * 3 / 2 + 1 = 16
- الزيادة التالية = 16 * 3 / 2 + 1 = 25
- الزيادة التالية = 25 * 3 / 2 + 1 = 39 وهكذا.
- قم بإنشاء مجموعة فقط عندما تحتاج إليها ، وإلا قم بتهيئتها لتصبح فارغة أو استخدم Collections.EMPTY_LIST .
- إذا كنت تعرف الحجم الدقيق المطلوب ، فحدده في مُنشئ المجموعة.
- إذا كنت متأكدًا من أن عدد العناصر لن يتجاوز 10 ، فلا تتردد في استخدام المُنشئ الافتراضي.
- الخطر المرتبط بإنشاء مجموعة ذات حجم صفري هو أن تكرار إنشاء صفائف جديدة ونسخ البيانات قد يكون أعلى. عليك أن تفكر مليًا فيما إذا كانت فائدة استخدام المجموعات ذات الحجم الصفري عظيمة حقًا أم لا .
- إذا قمت بتهيئة مجموعة كبيرة جدًا في بداية الطريقة وأردت تقليلها، فهناك طريقة TrimToSize() .
GO TO FULL VERSION