Mengeluarkan Elemen dari Koleksi Java

1. Gambaran keseluruhan

Dalam tutorial ringkas ini, kita akan membincangkan empat cara berbeza untuk membuang item dari Koleksi Java yang sesuai dengan predikat tertentu.

Kita secara semula jadi juga akan melihat beberapa peringatan.

2. Menentukan Koleksi Kami

Pertama, kita akan menggambarkan dua pendekatan yang mengubah struktur data asal. Kemudian kita akan membincangkan dua pilihan lain bahawa bukannya mengeluarkan item, akan membuat salinan Koleksi asal tanpa mereka.

Mari gunakan koleksi berikut di seluruh contoh kami untuk menunjukkan bagaimana kami dapat mencapai hasil yang sama menggunakan kaedah yang berbeza:

Collection names = new ArrayList(); names.add("John"); names.add("Ana"); names.add("Mary"); names.add("Anthony"); names.add("Mark");

3. Mengeluarkan Elemen Dengan Iterator

Java's Iterator membolehkan kita berjalan dan membuang setiap elemen dalam Koleksi .

Untuk melakukannya, pertama-tama kita perlu mengambil iterator ke atas elemennya menggunakan kaedah iterator . Selepas itu, kita dapat melawat setiap elemen dengan bantuan yang seterusnya dan menghapusnya dengan menggunakan remove :

Iterator i = names.iterator(); while(i.hasNext()) { String e = i.next(); if (e.startsWith("A")) { i.remove(); } }

Walaupun kesederhanaannya, ada beberapa peringatan yang harus kita pertimbangkan:

  • Bergantung pada koleksi, kami mungkin mengalami pengecualian ConcurrentModificationException
  • Kita perlu mengulang elemen sebelum dapat menghapusnya
  • Bergantung pada koleksi, pembuangan mungkin berkelakuan berbeza daripada yang diharapkan. Cth: ArrayList.Iterator membuang elemen dari koleksi dan mengalihkan data seterusnya ke kiri sedangkan, LinkedList.Iterator hanya menyesuaikan penunjuk ke elemen seterusnya. Oleh itu, LinkedList.Iterator berprestasi jauh lebih baik daripada ArrayList.Iterator semasa mengeluarkan item

4. Java 8 dan Collection.removeIf ()

Java 8 memperkenalkan kaedah baru untuk yang Collection antara muka yang menyediakan cara yang lebih ringkas untuk membuang unsur-unsur menggunakan Predikat :

names.removeIf(e -> e.startsWith("A"));

Penting untuk diperhatikan bahawa bertentangan dengan pendekatan Iterator , removeIf menunjukkan prestasi yang baik dalam LinkedList dan ArrayList .

Di Java 8, ArrayList mengesampingkan pelaksanaan lalai - yang bergantung pada Iterator - dan menerapkan strategi yang berbeza: pertama, ia mengulangi elemen dan menandakan yang sesuai dengan Predicate kami ; selepas itu, ia berulang kali untuk membuang (dan mengalihkan) elemen yang ditandai pada lelaran pertama.

5. Java 8 dan Pengenalan Aliran

Salah satu ciri utama baru di Java 8 adalah penambahan Stream (dan Pengumpul ). Terdapat banyak cara untuk membuat Aliran dari sumber. Namun, kebanyakan operasi yang mempengaruhi instance Stream tidak akan mengubah sumbernya, sebaliknya, API memfokuskan pada pembuatan salinan sumber dan melakukan operasi yang mungkin kita perlukan di dalamnya.

Mari kita lihat bagaimana kita dapat menggunakan Stream dan Pengumpul untuk mencari / menyaring elemen yang sesuai, dan tidak sesuai, Predicate kami .

5.1. Mengeluarkan Elemen Dengan Aliran

Mengalih keluar, atau lebih tepatnya, menyaring elemen menggunakan Aliran cukup mudah , kita hanya perlu membuat contoh Aliran menggunakan Koleksi kita , memanggil penapis dengan Predicate kami dan kemudian mengumpulkan hasilnya dengan bantuan Pengumpul:

Collection filteredCollection = names .stream() .filter(e -> !e.startsWith("A")) .collect(Collectors.toList());

Streaming kurang invasif daripada pendekatan sebelumnya, ini mendorong pengasingan dan memungkinkan penciptaan beberapa salinan dari sumber yang sama. Namun, kita harus ingat bahawa ia juga meningkatkan memori yang digunakan oleh aplikasi kita.

5.2. Pengumpul.partisiBoleh

Menggabungkan kedua-dua Stream.filter dan Pengumpul cukup berguna, walaupun kita mungkin menghadapi senario di mana kita memerlukan elemen yang sepadan dan tidak sepadan. Dalam kes sedemikian, kita dapat memanfaatkan Collectors.partitioningBy :

Map
    
      classifiedElements = names .stream() .collect(Collectors.partitioningBy((String e) -> !e.startsWith("A"))); String matching = String.join(",", classifiedElements.get(true)); String nonMatching = String.join(",", classifiedElements.get(false));
    

Kaedah ini mengembalikan Peta yang hanya mengandungi dua kunci, benar dan salah , masing-masing menunjuk ke senarai yang masing-masing mengandungi unsur pencocokan, dan tidak sepadan.

6. Kesimpulannya

Dalam artikel ini, kami melihat beberapa kaedah untuk membuang unsur dari Koleksi dan beberapa peringatan mereka.

Anda boleh mendapatkan kod sumber lengkap dan semua coretan kod untuk artikel ini di GitHub.