Standart savol tug'iladi: ro'yxatni qanday boshlash kerak? Quyidagi kod ishlamaydi: Bu kompilyatsiya xatosiga olib keladi: Mahalliy o'zgaruvchilar nomlari ishga tushirilmagan bo'lishi mumkin . Java spetsifikatsiyasi barcha mahalliy o'zgaruvchilarni (stekda mavjud bo'lganlar) tegishli qiymatlar bilan ishga tushirishni talab qiladi. Buni shunday qilishingiz mumkin: shubhasiz, ro'yxatni ishga tushirish kerak. Roʻyxatni birinchi qatorda yaratishingiz mumkin yoki siz aqlliroq ish qilishingiz va getAllNames() usulida qilganimiz kabi dangasa ishga tushirishdan foydalanishingiz mumkin . Bunday holda, ro'yxat faqat kerak bo'lganda tuziladi - agar dastlabki shartlar bajarilmasa, ro'yxat hech qachon uyada ko'rinmaydi. Bu erda biz asosiy savolga keldik: ro'yxat uchun qanday hajmni belgilashimiz kerak? Eng yaxshi variant - unga aniq o'lchamni berishdir. Masalan: Bu holda aniq n ta nom qaytarilishi kerak va natijada n ta elementdan iborat to'plam hosil bo'ladi. Biroq, n ning aniq qiymati har doim ham ma'lum emas. Hatto keltirilgan misolda ham, agar n=1000 va faqat 100 ta nom mavjud bo'lsa-chi? To'plamlar bilan ishlashda eng mashhur usul standart konstruktorni chaqirishdir. Agar Java manba kodiga qarasangiz (versiya 1.6) Ko'rib turganingizdek, sukut bo'yicha 10 ta elementdan iborat ro'yxat yaratilgan . Ya'ni, biz ro'yxatda 10 dan ortiq elementni saqlashni rejalashtirmaganimizda standart konstruktordan xavfsiz foydalanishimiz mumkin. Agar siz 11-elementni qo'shmoqchi bo'lsangiz nima bo'ladi? Xo'sh, hech qanday yomon narsa yo'q ... element muvaffaqiyatli qo'shiladi. Usulga qarang: massivning o'lchami provideCapacity usuli bilan boshqariladi . Hajmi 1,5 barobar ortadi . Yangi massiv yaratiladi va unga elementlar ko'chiriladi. Agar biz o'lchamni 10 ga qo'ysak, u holda 11-elementda:
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); } }
- hajmi 10 * 3/2 + 1 = 16 ga o'zgaradi
- keyingi o'sish = 16 * 3/2 + 1 = 25
- keyingi o'sish = 25 * 3/2 + 1 = 39 va boshqalar.
- To'plamni faqat kerak bo'lganda yarating , aks holda uni null qilib ishga tushiring yoki Collections.EMPTY_LIST dan foydalaning .
- Agar kerakli o'lchamni bilsangiz , uni to'plam konstruktorida belgilang.
- Elementlar soni 10 dan oshmasligiga ishonchingiz komil bo'lsa , standart konstruktordan foydalaning.
- Nol o'lchamli to'plamni yaratish bilan bog'liq xavf shundaki, yangi massivlarni yaratish va ma'lumotlarni nusxalash chastotasi yuqori bo'lishi mumkin. Nol o'lchamdagi to'plamlardan foydalanishning foydasi haqiqatan ham shunchalik katta yoki yo'qligini juda ehtiyotkorlik bilan o'ylab ko'rishingiz kerak .
- Agar siz usul boshida juda katta to'plamni ishga tushirgan bo'lsangiz va uni qisqartirmoqchi bo'lsangiz, trimToSize() usuli mavjud .
GO TO FULL VERSION