2011-08-11 54 views
212

Giả sử rằng arraylist được định nghĩa là ArrayList<String> arraylist, là arraylist.removeAll(arraylist) tương đương với arraylist.clear()?Sự khác nhau giữa ArrayList.clear() và ArrayList.removeAll() là gì?

Nếu có, tôi có thể giả định rằng phương pháp clear() có hiệu quả hơn để làm trống danh sách mảng không?

Có bất kỳ cảnh báo nào khi sử dụng arraylist.removeAll(arraylist) thay vì arraylist.clear() không?

+0

Một hệ quả có thể xảy ra đối với câu hỏi này: Khi nào một người có thể được sử dụng thay cho người khác? –

+3

@Corey: khi nào mọi người có thể muốn sử dụng 'arraylist.removeAll (arraylist)'? Tôi thấy hoàn toàn không có lý do để làm điều đó. –

+0

@Joachim Sauer Đó chính xác là những gì tôi muốn xác minh. Cảm ơn +2. Nhưng sự khác biệt giữa 'elementData [i] = null' và' e.remove() 'có ý nghĩa gì không? – ateiob

Trả lời

304

Các mã nguồn cho clear():

public void clear() { 
    modCount++; 

    // Let gc do its work 
    for (int i = 0; i < size; i++) 
     elementData[i] = null; 

    size = 0; 
} 

Các mã nguồn cho removeAll() (Theo quy định tại AbstractCollection):

public boolean removeAll(Collection<?> c) { 
    boolean modified = false; 
    Iterator<?> e = iterator(); 
    while (e.hasNext()) { 
     if (c.contains(e.next())) { 
      e.remove(); 
      modified = true; 
     } 
    } 
    return modified; 
} 

clear() là nhanh hơn nhiều vì nó không phải đối phó với tất cả những cuộc gọi phương thức bổ sung đó.

Và như Atrey chỉ ra, c.contains(..) làm tăng độ phức tạp của thời gian removeAll thành O (n^2) thay vì clear 's O (n).

+20

Một lưu ý rằng 'c.contains (...)' bình phương thời gian phức tạp của hoạt động sẽ làm cho câu trả lời này hoàn tất. – Atreys

+0

@ Jeffrey Sự khác nhau giữa 'elementData [i] = null' và' e.remove() 'là gì? – ateiob

+5

Nguồn là mạnh mẽ trong này. (Đối với tất cả các câu trả lời khác: Sử dụng nguồn, Lu-ca.) Lưu ý cách clear() có thể được triển khai như chỉ một dòng, size = 0; nhưng việc thu gom rác sẽ không biết thu thập các phần tử trong các phần không thể truy cập được của mảng đó. –

1

Xóa nhanh hơn vì nó không lặp qua các thành phần cần xóa. Phương pháp này có thể giả định rằng TẤT CẢ các phần tử có thể bị xóa.

Remove all không nhất thiết có nghĩa là xóa tất cả các phần tử trong danh sách, chỉ những yếu tố được cung cấp làm thông số NÊN được xóa. Do đó, cần nhiều nỗ lực hơn để giữ những thứ không bị xóa.

Làm rõ

By 'loop', tôi có nghĩa là nó không nhất thiết phải kiểm tra xem phần tử nên được giữ hay không. Nó có thể thiết lập các tham chiếu đến null mà không cần tìm kiếm thông qua danh sách các yếu tố được cung cấp để xóa.

Clear IS nhanh hơn deleteall.

+1

Tôi khá chắc chắn rằng 'ArrayList.clear()' cũng phải lặp lại. –

+0

@JVerstry Bạn có nghĩa là rõ ràng() ** không xóa ** các yếu tố nó loại bỏ khỏi ArrayList? – ateiob

+1

Sai, rõ ràng không lặp qua mảng nội bộ và đặt tất cả các tham chiếu thành null để cho phép trình thu gom rác thực hiện công việc của nó. – devconsole

4

Chúng phục vụ hai mục đích khác nhau. clear() chỉ xóa một thể hiện của lớp, removeAll() xóa tất cả các đối tượng đã cho và trả về trạng thái của thao tác.

+0

bạn có thể vui lòng cung cấp tài nguyên để đọc về vấn đề trên để tham khảo thêm –

+1

@KasunSiyambalapitiya Làm thế nào về [câu trả lời được chấp nhận] (http://stackoverflow.com/a/7032144/3040381), có chứa mã nguồn cho cả hai ? – Abdul

7

Trừ khi có một tối ưu hóa cụ thể để kiểm tra nếu đối số truyền cho removeAll() là bộ sưu tập riêng của mình (và tôi cao nghi ngờ rằng một tối ưu hóa như vậy là có) nó sẽ được đáng kể chậm hơn so với một đơn giản .clear().

Ngoài điều đó (và ít nhất quan trọng không kém): arraylist.removeAll(arraylist) chỉ là mã khó hiểu, khó hiểu. Đó là một cách rất lạc hậu khi nói "xóa bộ sưu tập này". Lợi ích nào sẽ có trên rất dễ hiểuarraylist.clear()?

1

clear() sẽ hiệu quả hơn nhiều. Nó sẽ đơn giản loại bỏ từng mục. Sử dụng removeAll (arraylist) sẽ mất nhiều công việc hơn vì nó sẽ kiểm tra mọi mục trong arraylist để xem nó có tồn tại trong arraylist hay không trước khi loại bỏ nó.

35

Độ phức tạp thời gian của ArrayList.clear()O(n) và của removeAllO(n^2).

Vì vậy, có, ArrayList.clear nhanh hơn nhiều.

9

Phương pháp clear() xóa tất cả các phần tử của một đơn ArrayList. Đó là một hoạt động nhanh, vì nó chỉ đặt một số phần tử mảng thành null.

Phương thức removeAll(Collection), được kế thừa từ AbstractCollection, xóa tất cả các phần tử trong bộ sưu tập đối số khỏi bộ sưu tập mà bạn gọi phương thức. Đó là một hoạt động tương đối chậm, vì nó phải tìm kiếm thông qua một trong những bộ sưu tập có liên quan.

3

clear() sẽ đi qua Mảng nằm bên dưới và đặt từng mục nhập là rỗng;

removeAll(collection) sẽ trải qua quá trình kiểm tra ArrayList để thu thập và remove(Object) nếu nó tồn tại.

Tôi tưởng tượng rằng clear() là cách nhanh hơn sau đó RemoveAll vì nó không so sánh vv

-5

Array => khi không gian được phân bổ cho một biến mảng tại thời gian chạy, không gian phân bổ không thể được mở rộng hoặc đã xóa.

ArrayList => Đây không phải là trường hợp trong danh sách mảng. ArrayList có thể phát triển và thu nhỏ tại thời gian chạy. Không gian được phân bổ có thể được thu nhỏ hoặc phóng to tại thời gian chạy.

+0

Điều này không trả lời câu hỏi đó là sự khác biệt giữa ArrayList.clear() và ArrayList.removeAll(), không phải là sự khác biệt giữa một mảng và một ArrayList. – Pierre

+0

Câu trả lời này là không cần thiết. Đó không phải là câu hỏi. –

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