JavaRush /Java blogi /Random-UZ /new ArrayList(????) qanday va qayerda ishga tushirish yax...
Vovan
Daraja

new ArrayList(????) qanday va qayerda ishga tushirish yaxshiroq

Guruhda nashr etilgan
To'plamlar ramkasidan foydalanmasdan kod yozish aqldan ozgan bo'lar edi. Bu juda yaxshi echimlarga ega Java-ning ajoyib qismi. Eng muhimi, massivlardan farqli o'laroq, siz o'lchamlar haqida tashvishlanishingiz shart emas. ArrayList xotirasi tugamaguncha o'sib boradi. Ishlab chiquvchi boshlang'ich o'lcham va ArrayIndexOutOfBoundsException xatosi haqida qayg'urishi shart emas . Ammo xotira miqdorini kuzatish uchun shart mavjud bo'lsa-chi? To'plamlar bilan ishlashda xotiradan samarali foydalana olamizmi?
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.
100 ta element bo'lsa, JVM bir necha marta yangi massiv yaratishi va elementlarni unga nusxalashi kerak bo'ladi. Buni hisobga olgan holda, massivning kerakli hajmi haqida taxmin mavjud bo'lsa, unga yaqin boshlang'ich sig'imni o'rnatish yaxshiroqdir. Bu erda harakatlar uchun ba'zi ko'rsatmalar mavjud:
  1. To'plamni faqat kerak bo'lganda yarating , aks holda uni null qilib ishga tushiring yoki Collections.EMPTY_LIST dan foydalaning .
  2. Agar kerakli o'lchamni bilsangiz , uni to'plam konstruktorida belgilang.
  3. Elementlar soni 10 dan oshmasligiga ishonchingiz komil bo'lsa , standart konstruktordan foydalaning.
  4. 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 .
  5. Agar siz usul boshida juda katta to'plamni ishga tushirgan bo'lsangiz va uni qisqartirmoqchi bo'lsangiz, trimToSize() usuli mavjud .
Albatta, ushbu ko'rsatmalar massivga asoslangan to'plamlar bilan ishlashda qo'llaniladi va ularning hech biri bog'langan ro'yxat holatida mantiqiy emas. Aslida, bu muammolar dasturning qotillari bo'lishi dargumon, lekin agar biroz yaxshiroq qilish imkoniyati mavjud bo'lsa, nega undan foydalanmaslik kerak. Boshqa foydali maslahatlaringiz bormi? Ishlarni yaxshilash yo'llarini topdingizmi? Yoki bularning barchasi keraksizmi? Siz nima deb o'ylaysiz?
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION