یک سوال استاندارد مطرح می شود: چگونه یک لیست را مقداردهی اولیه کنیم؟ کد زیر کار نخواهد کرد: منجر به خطای کامپایل می شود: ممکن است نام متغیرهای محلی مقداردهی اولیه نشده باشد . مشخصات جاوا مستلزم آن است که همه متغیرهای محلی (آنهایی که در پشته وجود دارند) با مقادیر مناسب مقداردهی اولیه شوند. به این صورت می توانید این کار را انجام دهید: بدون شک، لیست باید مقداردهی اولیه شود. میتوانید لیست را در خط اول ایجاد کنید یا میتوانید کاری هوشمندانهتر انجام دهید و از مقدار دهی اولیه مانند روش getAllNames() استفاده کنید . در این مورد، لیست فقط در صورت لزوم ایجاد می شود - اگر شرایط اولیه برآورده نشود، لیست هرگز در پشته ظاهر نمی شود. در اینجا به سوال اصلی می رسیم: چه اندازه برای لیست تعیین کنیم؟ بهترین گزینه این است که اندازه دقیق را به او بدهید. به عنوان مثال: در این حالت دقیقاً n نام باید برگردانده شود و در نتیجه مجموعه ای از n عنصر ایجاد می شود. با این حال، مقدار دقیق n همیشه مشخص نیست. حتی در مثال داده شده، اگر n=1000 و تنها 100 نام در دسترس باشد، چه؟ هنگام کار با مجموعه ها، محبوب ترین روش فراخوانی سازنده پیش فرض است. اگر به کد منبع جاوا نگاه کنید (نسخه 1.6) همانطور که می بینید، به طور پیش فرض لیستی از 10 عنصر ایجاد می شود . یعنی زمانی که قصد نداریم بیش از 10 عنصر را در لیست ذخیره کنیم، می توانیم با خیال راحت از سازنده پیش فرض استفاده کنیم. اگر بخواهید عنصر یازدهم را اضافه کنید چه اتفاقی می افتد؟ خوب، چیز بدی نیست ... عنصر با موفقیت اضافه خواهد شد. به روش نگاه کنید: اندازه آرایه با روش sureCapacity کنترل می شود . اندازه 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