2009-07-26 31 views

Trả lời

95

Tạo một sublist với hàng loạt các yếu tố mà bạn muốn loại bỏ và sau đó gọi clear trên danh sách trả lại.

list.subList(23, 45).clear() 

Cách tiếp cận này được nhắc đến như một thành ngữ trong tài liệu cho cả ListArrayList.


Đây là ví dụ về mã được kiểm tra đầy đủ!

// limit yourHappyList to ten items 
int k = yourHappyList.size(); 
if (k > 10) 
    yourHappyList.subList(10, k).clear(); 
    // sic k, not k-1 
+0

+1 có lẽ là thực hiện nhanh nhất mà giữ lại con trỏ đến bản gốc – akf

+0

Xác nhận bằng tài liệu chính thức https://docs.oracle.com/javase/6/docs/api/java/util/List.html#subList(int,%20int). "Ví dụ, thành ngữ sau loại bỏ một loạt các phần tử từ một danh sách: list.subList (từ, đến) .clear();" –

4

sử dụng ArrayList#removeRange() phương pháp:

protected void removeRange (int fromIndex, int toIndex)

Xóa khỏi danh sách này tất cả các yếu tố mà chỉ số này giữa fromIndex, toàn diện và toIndex , độc quyền. Thay đổi bất kỳ thành phần nào bên trái sang bên trái (giảm chỉ số của chúng). Cuộc gọi này rút ngắn danh sách bởi các phần tử (toIndex - fromIndex). (Nếu toIndex == fromIndex, thao tác này không có hiệu lực.)

sau đó sử dụng phương pháp ArrayList#trimToSize():

tính kỹ thuật cao năng lực thẩm ArrayList này là kích thước hiện tại của danh sách. Một ứng dụng có thể sử dụng thao tác này để giảm thiểu lưu trữ của một cá thể ArrayList.

+0

downvotes mà không cần giải thích là vô nghĩa – dfa

+6

phương pháp được bảo vệ ??? – ripper234

+0

nếu bạn không thể phân lớp, hãy thử subList (kiểm tra câu trả lời thứ hai của tôi) – dfa

0

Có một xem xét khác. Bạn có thể muốn tránh xa việc sử dụng ArrayList trong chữ ký phương thức của mình và thay vì làm việc với giao diện List, vì nó buộc bạn thực hiện ArrayList, hãy thực hiện các thay đổi trong dòng khó khăn nếu bạn thấy điều đó, ví dụ: LinkedList phù hợp với nhu cầu của bạn. Ngăn chặn khớp nối chặt chẽ này không có chi phí.

Một phương pháp khác có thể trông như thế này:

private void shrinkListTo(List<Result> list, int newSize) { 
    list.retainAll(list.subList(0, newSize); 
} 

Thật không may, phương pháp List.retainAll() là tùy chọn cho các lớp con để thực hiện, vì vậy bạn sẽ cần phải catch một UnsupportedOperationException, và sau đó làm cái gì khác.

private void shrinkListTo(List<Result> list, int newSize) { 
    try { 
    list.retainAll(list.subList(0, newSize); 
    } catch (UnspportedOperationException e) { 
    //perhaps log that your using your catch block's version. 
    for (int i = list.size() - 1; i >= newSize; --i) 
     list.remove(i); 
    } 
    } 
} 

Điều đó không thẳng tiến như ban đầu của bạn. Nếu bạn không bị ràng buộc với cá thể của Danh sách mà bạn đang chuyển vào, bạn có thể dễ dàng trả về một cá thể mới bằng cách gọi subList(int start, int end) và thậm chí bạn không cần phải thực hiện một phương thức. Điều này cũng sẽ được thực hiện nhanh hơn, như (trong Java 6), bạn sẽ nhận được một thể hiện của một AbstractList.SubList có chứa danh sách của bạn, một bù đắp vào nó và kích thước. Sẽ không cần lặp lại.

Nếu bạn quan tâm đến các đối số cho mã hóa để giao diện thay vì các lớp học, xem this favorite article by Allen Holub

+1

sử dụng .retainAll() sẽ thực sự không hiệu quả. nó sẽ phải lấy O (n^2) vì mỗi phần tử trong danh sách, nó phải đi qua danh sách con để kiểm tra nó (nó không biết rằng đó là một danh sách con) – newacct

7

cách khác bạn có thể sử dụng subList phương pháp:

public static <T> List<T> shrinkTo(List<T> list, int newSize) { 
    return list.subList(0, newSize - 1); 
} 
+0

yea nhưng điều này không ảnh hưởng đến danh sách gốc. có thể các yếu tố cần được loại bỏ không còn cần thiết nữa và anh ta muốn giải phóng chúng; phương pháp này sẽ không thực hiện được điều đó. – newacct

+1

GC sẽ chăm sóc nó – dfa

3

Giải pháp của tôi:

public static void shrinkTo(List list, int newSize) { 
    int size = list.size(); 
    if (newSize >= size) return; 
    for (int i = newSize; i < size; i++) { 
     list.remove(list.size() - 1); 
    } 
} 

Chỉ cần sử dụng:

shrinkTo(yourList, 6); 
+0

Dường như làm việc với tôi. Cảm ơn bạn! –

+0

Mức độ phức tạp sẽ là O (n * k); k = số cần được loại bỏ. Trong trường hợp xấu nhất nó sẽ đi đến O (nˆ2). –

Các vấn đề liên quan