Pre-Java 8 Anda harus menggunakan:
tourists.removeAll(Collections.singleton(null));
Penggunaan Post-Java 8:
tourists.removeIf(Objects::isNull);
Alasannya di sini adalah kompleksitas waktu. Masalah dengan array adalah bahwa operasi penghapusan dapat mengambil O (n) waktu untuk menyelesaikannya. Sungguh di Jawa ini adalah salinan array elemen yang tersisa dipindahkan untuk menggantikan tempat kosong. Banyak solusi lain yang ditawarkan di sini akan memicu masalah ini. Yang pertama secara teknis O (n * m) di mana m adalah 1 karena itu adalah nol tunggal: jadi O (n)
Anda harus menghapus semua singleton, secara internal ia melakukan batchRemove () yang memiliki posisi baca dan posisi tulis. Dan mengulang daftar. Ketika menyentuh nol, itu hanya mengulangi posisi baca oleh 1. Ketika mereka sama dengan yang dilewatinya, ketika mereka berbeda itu terus bergerak bersama menyalin nilai-nilai. Kemudian pada akhirnya dipotong untuk ukuran.
Ini secara efektif melakukan ini secara internal:
public static <E> void removeNulls(ArrayList<E> list) {
int size = list.size();
int read = 0;
int write = 0;
for (; read < size; read++) {
E element = list.get(read);
if (element == null) continue;
if (read != write) list.set(write, element);
write++;
}
if (write != size) {
list.subList(write, size).clear();
}
}
Yang dapat Anda lihat secara eksplisit adalah operasi O (n).
Satu-satunya hal yang bisa lebih cepat adalah jika Anda mengulang daftar dari kedua ujungnya, dan ketika Anda menemukan nol, Anda menetapkan nilainya sama dengan nilai yang Anda temukan di akhir, dan mengurangi nilai itu. Dan diulang sampai dua nilai cocok. Anda telah mengacaukan pesanan, tetapi akan sangat mengurangi jumlah nilai yang Anda set vs yang Anda tinggalkan sendiri. Yang merupakan metode yang bagus untuk diketahui tetapi tidak akan banyak membantu di sini karena .set () pada dasarnya gratis, tetapi bentuk delete adalah alat yang berguna untuk sabuk Anda.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Meskipun ini tampaknya cukup masuk akal, .remove () pada iterator secara internal memanggil:
ArrayList.this.remove(lastRet);
Yang lagi operasi O (n) dalam menghapus. Itu System.arraycopy () yang lagi-lagi bukan apa yang Anda inginkan, jika Anda peduli kecepatan. Ini membuatnya n ^ 2.
Ada juga:
while(tourists.remove(null));
Yaitu O (m * n ^ 2). Di sini kita tidak hanya mengulang daftar. Kami mengulangi seluruh daftar, setiap kali kami cocok dengan nol. Kemudian kami melakukan operasi n / 2 (rata-rata) untuk melakukan System.arraycopy () untuk melakukan penghapusan. Anda dapat benar-benar mengurutkan seluruh koleksi antara item dengan nilai dan item dengan nilai nol dan memotong akhir dalam waktu yang lebih singkat. Bahkan, itu berlaku untuk semua yang rusak. Setidaknya dalam teori, sistem yang sebenarnya. Arraycopy sebenarnya bukan operasi N dalam praktek. Secara teori, teori dan praktik adalah hal yang sama; dalam praktiknya tidak.
Iterator
? Gali java-doc. download.oracle.com/javase/6/docs/api/java/util/…