hiệu quả loại bỏ một số yếu tố từ một ArrayList
đòi hỏi một số suy nghĩ. Cách tiếp cận ngây thơ là một cái gì đó như thế này:
Iterator<DealerProductCount> it = wsResponse.Dealers.iterator();
while (it.hasNext()) {
if (it.next().ParentId != -10) {
it.remove();
}
}
Vấn đề là mỗi lần bạn loại bỏ phần tử bạn sao chép (trung bình) một nửa số phần tử còn lại. Điều này là do việc loại bỏ một phần tử khỏi ArrayList
đòi hỏi phải sao chép tất cả các phần tử sau khi phần tử đã xóa một vị trí sang trái.
Giải pháp ban đầu của bạn liên quan đến danh sách các thành phần cần xóa cũng thực sự giống nhau. Thật không may, các thuộc tính của một ArrayList
không cho phép removeAll
làm tốt hơn so với ở trên.
Nếu bạn mong đợi để loại bỏ một số yếu tố, sau đây là hiệu quả hơn:
ArrayList<DealerProductCount> retain =
new ArrayList<DealerProductCount>(wsResponse.Dealers.size());
for (DealerProductCount dealer : wsResponse.Dealers) {
if (dealer.ParentId == -10) {
retain.add(dealer);
}
}
// either assign 'retain' to 'wsResponse.Dealers' or ...
wsResponse.Dealers.clear();
wsResponse.Dealers.addAll(retain);
Chúng tôi đang sao chép (gần như) toàn bộ danh sách hai lần, vì vậy đây sẽ chia đều (trung bình) nếu bạn loại bỏ ít nhất là 4 phần tử.
Thật thú vị khi lưu ý rằng ngôn ngữ lập trình chức năng/thư viện điển hình hỗ trợ phương pháp lọc và có thể thực hiện tác vụ này trong một lần chuyển qua danh sách; tức là hiệu quả hơn rất nhiều. Tôi nghĩ chúng ta có thể mong đợi những cải tiến đáng kể nếu/khi Java hỗ trợ lambdas, và các API thu thập được nâng cao để sử dụng chúng.
Nguồn
2011-06-08 15:18:57
Có các cấu trúc dữ liệu khác để xóa mục nào hiệu quả hơn. Loại bỏ khỏi một LinkedList sẽ có hiệu suất O (n). Xóa khỏi HashMap sẽ có hiệu suất thời gian không đổi. –