CodeGym /Java Blog /Acak /Menghapus elemen dari ArrayList
John Squirrels
Level 41
San Francisco

Menghapus elemen dari ArrayList

Dipublikasikan di grup Acak
Hai! Di pelajaran terakhir, kami berkenalan dengan kelas ArrayList, dan belajar bagaimana melakukan operasi yang paling umum dengan kelas ini. Selain itu, kami menunjukkan beberapa perbedaan antara array biasa ArrayListdan array biasa. Namun kami melewatkan satu topik, yaitu, cara menghapus elemen dari file ArrayList. Kita akan membahasnya sekarang. Menghapus elemen dari ArrayList - 1Kami telah menyebutkan bahwa menghapus elemen dari array biasa sangat tidak nyaman. Karena kita tidak dapat menghapus elemen itu sendiri, kita hanya dapat "meniadakan" (mengatur ke nol) nilainya:

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 + '\'' +
               '}';
   }
}
Keluaran: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] Tapi menyetel elemen array ke null meninggalkan "lubang". Kami belum menghapus posisi dalam array, hanya isinya. Bayangkan apa yang akan terjadi jika kita memiliki susunan 50 kucing dan membuang 17 di antaranya dengan cara ini. Kami akan memiliki array dengan 17 lubang. Coba saja pantau mereka! Tidak realistis berharap untuk mengingat jumlah sel kosong tempat Anda dapat menulis nilai baru. Jika Anda membuat satu kesalahan, Anda akan menimpa referensi objek yang Anda inginkan. Ada, tentu saja, cara untuk melakukannya dengan sedikit lebih hati-hati: setelah menghapus elemen, pindahkan elemen ke depan array untuk meletakkan "lubang" di bagian akhir:

public static void main(String[] args) {

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

   cats[1] = null;

   for (int i = 2; i < cats.length-1; i++) {
       cats [i-1] = cats [i];// Move the elements to the front of the array, so the empty position is at the end
   }

   System.out.println(Arrays.toString(cats));
}
Keluaran: [Cat{name='Thomas'}, Cat{name='Fluffy'}, Cat{name='Fluffy'}, null] Ini tampaknya lebih baik, tetapi hampir tidak bisa disebut solusi yang tangguh. Jika tidak ada alasan lain selain fakta bahwa kita harus menulis kode ini setiap kali kita menghapus elemen dari array! Ini pilihan yang buruk. Kita bisa menggunakan cara lain dan membuat metode terpisah:

public void deleteCat(Cat[] cats, int indexToDelete) {
   //...delete the cat corresponding to the index and move the elements
}
Tapi ini juga tidak banyak berguna: metode ini hanya bisa bekerja dengan Catobjek, tapi tidak dengan tipe lain. Dengan kata lain, jika sebuah program memiliki 100 kelas lain yang ingin kita gunakan dengan array, kita harus menulis metode yang sama dengan logika yang persis sama di masing-masing kelas. Ini benar-benar bencana -_- Tapi ArrayListkelas memecahkan masalah ini! Itu menerapkan metode khusus untuk menghapus elemen:remove()

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.toString());

   cats.remove(1);

   System.out.println(cats.toString());
}
Kami meneruskan indeks objek kami ke metode, yang menghapusnya (seperti dalam array). Metode ini remove()memiliki dua fitur khusus. Pertama, tidak meninggalkan "lubang". Itu sudah mengimplementasikan logika yang diperlukan untuk menggeser elemen ketika sebuah elemen dihapus dari tengah, yang sebelumnya kami tulis sendiri. Lihatlah output dari kode sebelumnya:

[Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}]

[Cat{name='Thomas'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}]
Kami mengeluarkan satu kucing dari tengah, dan sisanya dipindahkan agar tidak ada ruang kosong. Kedua , dapat menghapus objek tidak hanya dengan indeks (seperti array normal), tetapi juga dengan referensi :

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.toString());

   cats.remove(lionel);

   System.out.println(cats.toString());
}
Keluaran: [Kucing{nama='Thomas'}, Kucing{name='Behemoth'}, Kucing{nama='Lionel Messi'}, Kucing{name='Fluffy'}] [Kucing{nama='Thomas'}, Cat{name='Behemoth'}, Cat{name='Fluffy'}] Ini bisa sangat nyaman jika Anda tidak ingin selalu melacak indeks objek yang diinginkan. Tampaknya kami telah menemukan penghapusan biasa. Sekarang mari kita bayangkan situasi ini: kita ingin mengulangi daftar kita dan menghapus kucing dengan nama tertentu . Untuk melakukannya, kita akan menggunakan fast forloop (juga disebut for-each loop), yang telah diperkenalkan kepada kita dalam pelajaran Rishi:

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);

   for (Cat cat: cats) {

       if (cat.name.equals("Behemoth")) {
           cats.remove(cat);
       }
   }

   System.out.println(cats);
}
Kode terlihat sangat logis. Tapi hasilnya mungkin kejutan besar: Pengecualian di thread "main" java.util.ConcurrentModificationException di java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) di java.util.ArrayList$Itr.next(ArrayList. java:831) di Cat.main(Cat.java:25) Ada semacam kesalahan, dan tidak jelas mengapa hal itu terjadi. Proses ini melibatkan sejumlah nuansa yang harus diperhatikan. Inilah aturan umum yang perlu Anda ingat: Anda tidak dapat mengulang koleksi secara bersamaan dan mengubah elemennya. Dan yang kami maksud adalah perubahan apa pun, bukan hanya penghapusan. Jika Anda mengganti pemindahan kucing dengan upaya memasukkan kucing baru, hasilnya akan sama:

for (Cat cat: cats) {

   cats.add(new Cat("Salem Saberhagen"));
}

System.out.println(cats);
Pengecualian di utas "utama" java.util.ConcurrentModificationException di java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) di java.util.ArrayList$Itr.next(ArrayList.java:831) di Cat.main( Cat.java:25) Kami mengubah satu operasi ke operasi lainnya, tetapi hasilnya tidak berubah: kami mendapatkan ConcurrentModificationException yang sama . Itu terjadi justru ketika kami mencoba melanggar aturan di atas dengan mengubah daftar sambil mengulanginya. Di Java, kita memerlukan objek khusus yang disebut iterator (Iteratorkelas) untuk menghapus item saat melakukan iterasi pada koleksi. KelasIteratorbertanggung jawab untuk mengulang daftar elemen dengan aman. Ini cukup sederhana, karena hanya memiliki 3 metode:
  • hasNext()- mengembalikan benar atau salah, tergantung apakah ada item berikutnya dalam daftar, atau kita sudah mencapai item terakhir.
  • next()- mengembalikan item berikutnya dalam daftar
  • remove()- menghapus item dari daftar
Seperti yang Anda lihat, iterator dibuat khusus untuk kebutuhan kita, dan pada saat yang sama tidak ada yang rumit tentangnya. Misalkan kita ingin memeriksa apakah ada elemen berikutnya dalam daftar kita, dan tampilkan jika ada:

Iterator<Cat> catIterator = cats.iterator();// Create an iterator
while(catIterator.hasNext()) {// As long as there are elements in the list
  
   Cat nextCat = catIterator.next();// Get the next element
   System.out.println(nextCat);// Display it
}
Output: Cat{name='Thomas'} Cat{name='Behemoth'} Cat{name='Lionel Messi'} Cat{name='Fluffy'} Seperti yang Anda lihat, telah menerapkan metode ArrayListkhusus untuk membuat iterator: iterator(). Selain itu, perhatikan bahwa ketika kita membuat sebuah iterator, kita menentukan kelas objek yang akan bekerja dengannya ( <Cat>). Intinya adalah iterator dengan mudah menangani tugas awal kita. Misalnya, hapus kucing bernama "Lionel Messi":

Iterator<Cat> catIterator = cats.iterator();// Create an iterator
while(catIterator.hasNext()) {// As long as there are elements in the list

   Cat nextCat = catIterator.next();// Get the next element
   if (nextCat.name.equals("Lionel Messi")) {
       catIterator.remove();// Delete the cat with the specified name
   }
}

System.out.println(cats);
Keluaran: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Fluffy'}] Anda mungkin memperhatikan bahwa kami tidak menentukan indeks atau nama dalam remove()metode iterator ! Iterator lebih pintar dari yang terlihat: remove()menghapus elemen terakhir yang dikembalikan oleh iterator. Seperti yang Anda lihat, itu melakukan apa yang kami inginkan :) Pada prinsipnya, ini semua yang perlu Anda ketahui tentang menghapus elemen dari file ArrayList. Yah, hampir semuanya. Di pelajaran selanjutnya, kita akan melihat ke dalam kelas ini, dan melihat apa yang terjadi di sana selama berbagai pemanggilan metode :) Sampai saat itu!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION