JavaRush /Blog Java /Random-MS /new ArrayList(????) bagaimana dan di mana lebih baik untu...
Vovan
Tahap

new ArrayList(????) bagaimana dan di mana lebih baik untuk memulakan

Diterbitkan dalam kumpulan
Menulis kod tanpa menggunakan rangka kerja koleksi akan menjadi gila. Ini adalah bahagian Java yang indah dengan banyak penyelesaian yang kemas. Lebih penting lagi, tidak seperti tatasusunan, anda tidak perlu risau tentang saiz. ArrayList akan berkembang sehingga ia kehabisan memori. Pembangun tidak perlu risau tentang saiz awal dan ralat ArrayIndexOutOfBoundsException . Tetapi bagaimana jika terdapat syarat untuk memantau jumlah memori? Bolehkah kita menggunakan memori dengan cekap apabila bekerja dengan koleksi?
Soalan standard timbul: bagaimana untuk memulakan senarai? Kod di bawah tidak akan berfungsi: Ia akan mengakibatkan ralat penyusunan: Nama pembolehubah tempatan mungkin tidak dimulakan . Spesifikasi Java memerlukan semua pembolehubah tempatan (yang wujud pada tindanan) dimulakan dengan nilai yang sesuai. Inilah cara anda boleh melakukannya: Tanpa ragu-ragu, senarai mesti dimulakan. Anda boleh sama ada membuat senarai pada baris pertama, atau anda boleh melakukan sesuatu yang lebih bijak dan menggunakan pengamulaan malas seperti yang kami lakukan dalam kaedah getAllNames() . Dalam kes ini, senarai hanya akan dibuat apabila perlu - jika syarat awal tidak dipenuhi, senarai itu tidak akan muncul pada timbunan. Di sini kita sampai kepada soalan utama: apakah saiz yang perlu kita tetapkan untuk senarai? Pilihan terbaik ialah memberinya saiz yang tepat. Sebagai contoh: Dalam kes ini, betul-betul n nama mesti dikembalikan, dan sebagai akibatnya, koleksi n elemen dicipta. Walau bagaimanapun, nilai sebenar n tidak selalu diketahui. Walaupun dalam contoh yang diberikan, bagaimana jika n=1000 dan terdapat hanya 100 nama yang tersedia? Apabila bekerja dengan koleksi, kaedah yang paling popular ialah memanggil pembina lalai. Jika anda melihat kod sumber Java (versi 1.6) Seperti yang anda lihat, secara lalai senarai 10 elemen dicipta . Iaitu, kita boleh menggunakan pembina lalai dengan selamat apabila kita tidak merancang untuk menyimpan lebih daripada 10 elemen dalam senarai. Apa yang berlaku jika anda cuba menambah elemen ke-11? Baiklah, tiada apa-apa yang buruk... elemen itu akan berjaya ditambahkan. Lihat kaedah: Saiz tatasusunan dikawal oleh kaedah ensureCapacity . Saiznya bertambah 1.5 kali ganda . Tatasusunan baru dicipta dan unsur-unsur dipindahkan ke dalamnya. Jika kita menetapkan saiz kepada 10, maka pada elemen ke-11:
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); } }
  • saiz berubah kepada 10 * 3 / 2 + 1 = 16
  • kenaikan seterusnya = 16 * 3 / 2 + 1 = 25
  • kenaikan seterusnya = 25 * 3 / 2 + 1 = 39 dan seterusnya.
Dalam kes 100 elemen, JVM perlu mencipta tatasusunan baharu beberapa kali dan menyalin elemen ke dalamnya. Dengan mengambil kira perkara ini, jika terdapat andaian tentang saiz tatasusunan yang diperlukan, lebih baik untuk menetapkan kapasiti awal hampir dengannya. Berikut ialah beberapa garis panduan untuk tindakan:
  1. Buat koleksi hanya apabila anda memerlukannya , jika tidak mulakan koleksi itu menjadi batal atau gunakan Collections.EMPTY_LIST .
  2. Jika anda tahu saiz yang tepat diperlukan , nyatakan ia dalam pembina koleksi.
  3. Jika anda pasti bahawa bilangan elemen tidak akan melebihi 10 , jangan ragu untuk menggunakan pembina lalai.
  4. Risiko yang dikaitkan dengan mencipta koleksi bersaiz sifar ialah kekerapan mencipta tatasusunan baharu dan menyalin data mungkin lebih tinggi. Anda perlu berfikir dengan teliti sama ada faedah menggunakan koleksi bersaiz sifar benar-benar hebat .
  5. Jika anda memulakan koleksi terlalu besar pada permulaan kaedah dan ingin mengurangkannya, terdapat kaedah trimToSize() .
Sudah tentu, garis panduan ini digunakan apabila bekerja dengan koleksi berasaskan tatasusunan, dan semua ini tidak masuk akal dalam kes senarai terpaut. Sebenarnya, masalah ini tidak mungkin menjadi pembunuh program, tetapi jika ada peluang untuk melakukan lebih baik sedikit, mengapa tidak menggunakannya. Adakah anda mempunyai petua lain yang berguna? Adakah anda telah menemui cara untuk menjadikan sesuatu berfungsi dengan lebih baik? Atau adakah ini semua tidak perlu? Apa pendapat kamu?
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION