2016-02-22 12 views
13

ArrayList kế thừa equals triển khai từ cấp độ gốc AbstractList không thực sự hiệu quả.Tại sao ArrayList không ghi đè bằng() cho hiệu suất tốt hơn?

Trước tiên, nó có thể kiểm tra kích thước của hai ArrayLists và sau đó trả lại false ngay lập tức nếu các kích thước này khác nhau. Tại sao không ArrayList làm điều đó?

+0

hãy thử đọc chủ đề này http://programmers.stackexchange.com/questions/239139/why-do-arrays-in-java-not-override-equals –

+1

tôi không nghĩ rằng [này ] (http://stackoverflow.com/questions/18958113/jdk-implementation-of-abstractlistequals-does-not-check-for-list-size-equali) câu hỏi là một bản sao, bỏ phiếu cho mở lại. – Maroun

Trả lời

7

Như đã nêu trong this answer, điều này không được thực hiện vì một số việc triển khai có O (n) sự phức tạp của phương pháp size của họ, vì vậy điều này có thể thực sự là một suy thoái .

Tôi đồng ý rằng làm equals nhất quán trong tất cả danh sách triển khai có thể ảnh hưởng đến các bộ sưu tập có O (1) kích thước phức tạp, nhưng có lẽ các nhà phát triển Java nghĩ rằng nó nhiều dễ dàng hơn để chèn nó khi bạn cần vì xóa khi bạn don' t (bạn sẽ phải triển khai lại toàn bộ phương thức!). Ví dụ, bạn có thể dễ dàng thêm tối ưu hóa này với một cái gì đó như:

public boolean equals(Object o) { 
    // here it is 
    if (o instanceof List && this.size() != ((List)o).size()) 
     return false; 

    // call the parent equals 
    return super.equals(o); 

Nhưng nếu nó ban đầu được thực hiện với việc kiểm tra kích thước (trong lớp trừu tượng), bạn phải tái thực hiện toàn bộ phương pháp và loại bỏ các kích thước kiểm tra:

public boolean equals(Object o) { 
    if (o == this) 
     return true; 
    if (!(o instanceof List)) 
     return false; 

    ListIterator<E> e1 = listIterator(); 
    ListIterator<?> e2 = ((List<?>) o).listIterator(); 
    while (e1.hasNext() && e2.hasNext()) { 
     E o1 = e1.next(); 
     Object o2 = e2.next(); 
     if (!(o1==null ? o2==null : o1.equals(o2))) 
      return false; 
    } 
    return !(e1.hasNext() || e2.hasNext()); 
} 
+1

Ah, những gì tôi đã bỏ lỡ khi tôi đang nghĩ về nó - mặc dù việc thực hiện mặc định 'size()' là 'O (1)', nó không phải là 'final', vì vậy bạn không thể đảm bảo rằng nó không bị ghi đè. Obvs. –

+0

Có lẽ tôi chưa tỉnh táo, nhưng ... bạn không thể gọi 'return super.equals (o);' thay vì tự thực hiện lặp lại? – Marco13

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