2017-06-21 15 views
5

Trong Java tôi có thể xoá các mục từ một danh sách với mã này:Làm thế nào để lọc danh sách tại chỗ với Kotlin?

private void filterList(List<Item> items) { 
    Iterator<Item> iterator = items.iterator(); 
    while (iterator.hasNext()) { 
     if (checkItem(iterator.next())) { 
      iterator.remove(); 
     } 
    } 
} 

Làm thế nào để thực hiện như nhau trong Kotlin (ví dụ: loại bỏ một số mặt hàng trong một List mà không tái tạo)?

+0

tại sao android thẻ? – user7294900

+3

chỉ cần sao chép mã này vào tệp kotlin, IDE tự động làm điều đó cho bạn. – chandil03

Trả lời

12

Chỉ cần sử dụng .retainAll { ... } hoặc .removeAll { ... }, cả hai chấp nhận một vị ngữ, để lọc nó tại chỗ:

items.retainAll { shouldRetain(it) } 

items.removeAll { shouldRemove(it) } 

Lưu ý rằng items phải là một MutableList<T> cho rằng, không chỉ List<T> , đó là một danh sách chỉ đọc trong Kotlin và do đó không tiếp xúc với bất kỳ chức năng đột biến nào (xem: Collections trong tài liệu tham khảo ngôn ngữ).

Bằng cách này, hai chức năng này được thực hiện một cách hiệu quả cho các danh sách có hỗ trợ truy cập ngẫu nhiên: sau đó danh sách không đầm sau mỗi mục được lấy ra (O (n) Hiện trường hợp xấu nhất), và thay vào đó các mục được di chuyển trong danh sách khi nó được xử lý, cho thời gian O (n).


Và nếu bạn không muốn thay đổi danh sách ban đầu, bạn có thể tạo ra một bộ sưu tập riêng biệt với chỉ các mục mà bạn muốn giữ lại sử dụng .filter { ... } hoặc .filterNot { ... }, điều này sẽ làm việc cho read-only List<T> cũng :

val filtered = items.filter { shouldRetain(it) } 

val filtered = items.filterNot { shouldRemove(it) } 
+1

Tôi sẽ choáng váng nếu không có chức năng cho việc này. Thư viện chuẩn là tuyệt vời. – zsmb13

+1

Ý của bạn là 'removeAll'? Bởi vì trong câu hỏi một mục được loại bỏ khi vị từ * chuyển *. – Ilya

+0

@ Ilya, cảm ơn, nó chỉ là cái tên 'checkItem' làm tôi bối rối. Đã sửa. – hotkey

2

Kotlin có rất nhiều chức năng gọn gàng built-in. Bạn có thể thử sử dụng filter tại đây.

val filteredItems = items.filter { checkItem(it) } 

Thật không may, nó sẽ tạo lại danh sách. API này được thiết kế nhằm mục đích tránh tính đột biến thêm.

Nhưng nếu bạn vẫn muốn tiếp tục với việc sử dụng MutableList retainAll phương pháp

items.retainAll { checkItem(it) } 
Các vấn đề liên quan