Перед Java-8 вам слід скористатися:
tourists.removeAll(Collections.singleton(null));
Використання Post-Java 8:
tourists.removeIf(Objects::isNull);
Причина тут - складність у часі. Проблема з масивами полягає в тому, що операція з видалення може зайняти час (O) n. Дійсно в Java це копія масиву решти елементів, що переміщуються, щоб замінити порожнє місце. Багато інших запропонованих тут рішень спровокують це питання. Перший технічно O (n * m), де m дорівнює 1, тому що це одинаковий нуль: тому O (n)
Ви повинні вилучити всі одиночні, внутрішньо він робить batchRemove (), який має позицію читання та позицію запису. І це повторює список. Коли вона потрапляє в нуль, вона просто ітератує позицію зчитування на 1. Коли вони однакові, вона проходить, коли вони різні, вона продовжує рухатися вздовж копіювання значень. Потім в кінці вона підрізається за розміром.
Це ефективно робить це внутрішньо:
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();
}
}
Яке ви можете явно бачити, це операція O (n).
Єдине, що коли-небудь може бути швидшим, це якщо ви повторили список з обох кінців, і коли ви знайшли нуль, ви встановите його значення, яке дорівнює значенню, яке ви знайшли в кінці, і зменшили це значення. І повторюється, поки два значення не збігаються. Ви б зіпсували порядок, але значно зменшите кількість встановлених вами значень порівняно з тими, які ви залишили в спокої. Який хороший метод знати, але тут не дуже допоможе, оскільки .set () в основному безкоштовний, але ця форма видалення є корисним інструментом для вашого пояса.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Хоча це здається досить розумним, .remove () на ітераторі внутрішньо викликає:
ArrayList.this.remove(lastRet);
Це знову ж таки операція O (n) у межах видалення. Він робить System.arraycopy (), який знову не є тим, що ви хочете, якщо ви дбаєте про швидкість. Це робить n ^ 2.
Також є:
while(tourists.remove(null));
Що є O (m * n ^ 2). Тут ми не лише повторюємо список. Ми повторюємо весь список, кожен раз, коли ми відповідаємо нулю. Тоді ми робимо n / 2 (середні) операції, щоб зробити System.arraycopy () для виконання видалення. Ви могли б абсолютно дослівно сортувати всю колекцію між предметами зі значеннями та предметами з нульовими значеннями та обрізати закінчення за менший час. Насправді це справедливо для всіх зламаних. Принаймні теоретично, фактична system.arraycopy насправді не є N операцією на практиці. В теорії теорія і практика - це одне і те ж; на практиці це не так.
Iterator
? Копайте java-doc. download.oracle.com/javase/6/docs/api/java/util/…