Pre-Java 8 bạn nên sử dụng:
tourists.removeAll(Collections.singleton(null));
Sử dụng sau Java 8:
tourists.removeIf(Objects::isNull);
Lý do ở đây là thời gian phức tạp. Vấn đề với mảng là một hoạt động gỡ bỏ có thể mất thời gian O (n) để hoàn thành. Thực sự trong Java đây là một bản sao của các phần tử còn lại đang được di chuyển để thay thế vị trí trống. Nhiều giải pháp khác được cung cấp ở đây sẽ kích hoạt vấn đề này. Cái trước là về mặt kỹ thuật O (n * m) trong đó m là 1 vì nó là một đơn vị null: vì vậy O (n)
Bạn nên loại bỏTất cả các singleton, bên trong nó thực hiện một batchRemove () có vị trí đọc và vị trí ghi. Và lặp lại danh sách. Khi nó đạt null, nó chỉ đơn giản lặp lại vị trí đọc bằng 1. Khi chúng giống nhau, khi chúng khác nhau, nó tiếp tục di chuyển dọc theo sao chép các giá trị. Sau đó, ở cuối nó cắt theo kích thước.
Nó thực sự làm điều này trong nội bộ:
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();
}
}
Mà bạn có thể thấy rõ ràng là một hoạt động O (n).
Điều duy nhất có thể nhanh hơn là nếu bạn lặp lại danh sách từ cả hai đầu và khi bạn tìm thấy null, bạn đặt giá trị của nó bằng với giá trị bạn tìm thấy ở cuối và giảm giá trị đó. Và lặp đi lặp lại cho đến khi hai giá trị khớp nhau. Bạn đã làm xáo trộn trật tự, nhưng sẽ giảm đáng kể số lượng giá trị bạn đặt so với giá trị bạn để lại một mình. Đây là một phương pháp tốt để biết nhưng sẽ không giúp ích nhiều ở đây vì .set () về cơ bản là miễn phí, nhưng hình thức xóa đó là một công cụ hữu ích cho vành đai của bạn.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Trong khi điều này có vẻ đủ hợp lý, .remove () trên iterator gọi nội bộ:
ArrayList.this.remove(lastRet);
Đó là một lần nữa hoạt động O (n) trong loại bỏ. Nó thực hiện một System.arraycopy () một lần nữa không phải là điều bạn muốn, nếu bạn quan tâm đến tốc độ. Điều này làm cho nó n ^ 2.
Ngoài ra còn có:
while(tourists.remove(null));
Đó là O (m * n ^ 2). Ở đây chúng tôi không chỉ lặp lại danh sách. Chúng tôi nhắc lại toàn bộ danh sách, mỗi lần chúng tôi khớp với null. Sau đó, chúng tôi thực hiện n / 2 (trung bình) để thực hiện System.arraycopy () để thực hiện xóa. Bạn hoàn toàn có thể theo nghĩa đen, sắp xếp toàn bộ bộ sưu tập giữa các mục với các giá trị và các mục có giá trị null và cắt kết thúc trong thời gian ngắn hơn. Trong thực tế, điều đó đúng cho tất cả những người bị hỏng. Ít nhất là trên lý thuyết, thực tế system.arraycopy không thực sự là một hoạt động N trong thực tế. Về lý thuyết, lý thuyết và thực hành là như nhau; trong thực tế họ không.
Iterator
? Đào java-doc. download.oracle.com/javase/6/docs/api/java/util/ từ