Hai! Dalam pelajaran sebelumnya, kami menyelam lebih mendalam ke dalam tatasusunan dan menyemak contoh biasa bekerja dengan tatasusunan. Dalam pelajaran ini, kami akan mengambil ulasan lebih dekat di Java ArrayList. Secara umum, tatasusunan sangat berguna. Dan, seperti yang telah anda perhatikan, anda boleh melakukan banyak perkara dengan mereka :) Tetapi tatasusunan memang mempunyai beberapa kelemahan.
  • Saiz terhad. Anda perlu tahu berapa banyak elemen tatasusunan anda perlu mengandungi pada masa anda menciptanya. Jika anda memandang rendah, maka anda tidak akan mempunyai ruang yang mencukupi. Anggarkan terlalu tinggi, dan tatasusunan akan kekal separuh kosong, yang juga buruk. Lagipun, anda masih memperuntukkan lebih banyak memori daripada yang diperlukan.

  • Tatasusunan tidak mempunyai kaedah untuk menambah elemen. Anda mesti sentiasa menunjukkan secara eksplisit indeks kedudukan tempat anda ingin menambah elemen. Jika anda secara tidak sengaja menentukan indeks untuk kedudukan yang diduduki oleh beberapa nilai yang anda perlukan, ia akan ditimpa.

  • Tiada kaedah untuk memadam item. Nilai hanya boleh "disifarkan".

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;

      
      
       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Output: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] Nasib baik, pencipta Java sangat mengetahui kelebihan dan kekurangan tatasusunan, dan oleh itu mencipta struktur data yang sangat menarik yang dipanggil Java ArrayList . Bercakap semudah mungkin, Java ArrayList ialah tatasusunan "soup up" dengan banyak ciri baharu.

Cara Membuat ArrayList

Ia sangat mudah untuk dibuat:

ArrayList<Cat> cats = new ArrayList<Cat>();
Kini kami telah mencipta senarai untuk menyimpan objek Cat . Ambil perhatian bahawa kami tidak menyatakan saiz ArrayList , kerana ia boleh berkembang secara automatik. Bagaimana ini boleh berlaku? Ia agak mudah, sebenarnya. Ia mungkin mengejutkan anda, tetapi ArrayList dalam Java dibina di atas tatasusunan yang sangat biasa :) Ya, ia mengandungi tatasusunan, dan di situlah elemen kami disimpan. Tetapi ArrayList di Java mempunyai cara khas untuk bekerja dengan tatasusunan itu:
  • Apabila tatasusunan dalaman diisi, ArrayList mencipta tatasusunan baharu secara dalaman. Saiz tatasusunan baharu ialah saiz tatasusunan lama dikali 1.5 tambah 1.

  • Semua data disalin dari tatasusunan lama ke yang baru

  • Susunan lama dibersihkan oleh pemungut sampah.
Mekanisme ini membenarkan Java ArrayList (tidak seperti tatasusunan biasa) untuk melaksanakan kaedah untuk menambah elemen baharu. Ia adalah add()kaedahnya

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Behemoth"));
}
Item baharu ditambahkan pada penghujung senarai. Kini tiada risiko melimpahi tatasusunan, jadi kaedah ini benar-benar selamat. Dengan cara ini, ArrayList bukan sahaja boleh mencari objek dengan indeksnya, tetapi juga sebaliknya: ia boleh menggunakan rujukan untuk mencari indeks objek dalam ArrayList ! Inilah kegunaan kaedah indexOf() : Kami menghantar rujukan kepada objek yang kami mahu, dan indexOf() mengembalikan indeksnya:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Output: 0 Betul. Objek thomas kami sememangnya disimpan dalam elemen 0. Tatasusunan bukan sahaja mempunyai kelemahan. Mereka juga mempunyai kelebihan yang tidak dapat dipertikaikan. Salah satunya ialah keupayaan untuk mencari elemen mengikut indeks. Kerana kita menunjuk ke indeks, iaitu ke alamat memori tertentu, mencari tatasusunan dengan cara ini adalah sangat cepat. ArrayListtahu bagaimana untuk melakukannya juga! Kaedah get () melaksanakan ini:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Output: Cat{name='Behemoth'} Selain itu, anda boleh mengetahui dengan mudah sama ada ArrayList mengandungi objek tertentu. Ini dilakukan menggunakan kaedah ArrayList contains():

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.remove(fluffy);
   System.out.println(cats.contains(fluffy));
}
Kaedah menyemak sama ada tatasusunan dalaman ArrayList mengandungi elemen dan mengembalikan boolean (benar atau palsu). Output: palsu Dan satu lagi perkara penting tentang sisipan. ArrayList membolehkan anda menggunakan indeks untuk memasukkan elemen bukan sahaja pada penghujung tatasusunan, tetapi di mana-mana sahaja. Ia mempunyai dua kaedah untuk ini:
  • ArrayList add(int index, Cat element)
  • Set ArrayList (int index, elemen Cat)
Sebagai hujah, kedua-dua kaedah ini mengambil indeks kedudukan yang anda ingin masukkan dan rujukan kepada objek itu sendiri. Perbezaannya ialah memasukkan menggunakan set() menimpa nilai lama. Memasukkan menggunakan add() beralih pertama oleh satu semua elemen dari [index] ke penghujung tatasusunan, dan kemudian menambah objek yang ditentukan dalam kedudukan kosong yang terhasil.

Berikut ialah contoh:


public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set

   System.out.println(cats.toString());
}
Output: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] Kami mempunyai senarai 2 kucing . Kemudian kami memasukkan satu lagi sebagai elemen 0 menggunakan kaedah set() . Akibatnya, elemen lama telah digantikan dengan yang baru.

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add

   System.out.println(cats.toString());
}
Dan di sini kita melihat bahawa add() berfungsi secara berbeza. Ia menggerakkan semua elemen ke kanan dan kemudian menulis nilai baharu sebagai elemen 0. Output: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] Untuk mengosongkan senarai sepenuhnya, kami menggunakan kaedah clear() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.clear();

   System.out.println(cats.toString());
}
Output: [] Semuanya telah dialih keluar daripada senarai. Dengan cara ini, sila ambil perhatian: tidak seperti tatasusunan, ArrayList mengatasi kaedah toString() dan sudah memaparkan senarai dengan sewajarnya sebagai rentetan. Dengan tatasusunan biasa, kami terpaksa menggunakan kelas Tatasusunan untuk ini. Dan kerana saya menyebut Arrays : Java membolehkan anda "bertukar" dengan mudah antara array dan ArrayList , iaitu menukar satu kepada yang lain. Kelas Arrays mempunyai kaedah Arrays.asList() untuk ini. Kami menggunakannya untuk mendapatkan kandungan sebagai tatasusunan dan menyerahkannya kepada pembina ArrayList kami:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   Cat[] catsArray = {thomas, behemoth, lionel, fluffy};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Output: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] Anda juga boleh pergi ke arah yang bertentangan: dapatkan tatasusunan daripada objek ArrayList . Kami melakukan ini menggunakan kaedah toArray() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
Nota: kami menghantar tatasusunan kosong kepada kaedah toArray() . Ini bukan kesilapan. Di dalam kelas ArrayList , kaedah ini dilaksanakan dengan cara yang melepasi tatasusunan kosong meningkatkan prestasinya. Hanya ingat perkara ini untuk masa hadapan (sudah tentu, anda boleh lulus tatasusunan beberapa saiz tertentu; itu juga akan berfungsi). Oh, kira-kira saiznya. Saiz semasa senarai boleh didapati menggunakan kaedah size() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Adalah penting untuk memahami bahawa tidak seperti sifat panjang tatasusunan , kaedah ArrayList.size() mengembalikan bilangan elemen sebenar, bukan kapasiti asal. Lagipun, kami tidak menentukan saiz semasa membuat ArrayList . Walau bagaimanapun, anda boleh menentukannya — ArrayList mempunyai pembina yang sesuai. Tetapi dari segi menambah elemen baharu, ini tidak mengubah tingkah lakunya:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);// create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Output konsol: 4 Kami telah mencipta senarai 2 elemen, tetapi ia berkembang secara senyap apabila kami memerlukannya. Pertimbangan lain ialah jika kita membuat senarai yang sangat kecil pada mulanya, ia perlu berkembang lebih kerap, yang akan menggunakan beberapa sumber. Kami hampir tidak menyentuh proses mengalih keluar elemen daripada ArrayList dalam pelajaran ini Sudah tentu, ini bukan kerana ia tergelincir dalam fikiran kita. Kami telah meletakkan topik ini ke dalam pelajaran berasingan yang akan anda temui kemudian :) Untuk mengukuhkan perkara yang anda pelajari, kami cadangkan anda menonton pelajaran video daripada Kursus Java kami