2013-09-23 75 views
14

Kỳ lạ mặc định JDK 6 thi hành AbstractList::equals()không dường như để kiểm tra đầu tiên nếu hai danh sách có cùng kích thước:JDK thi hành AbstractList :: equals() không kiểm tra danh sách bình đẳng kích thước đầu tiên

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()); 
} 

Nếu cả hai danh sách chứa nhiều mục hoặc các mục cần thời gian để so sánh, các mục sẽ so sánh tất cả trước khi nhận ra rằng một danh sách ngắn hơn danh sách kia; mà dường như tôi thực sự không hiệu quả vì sự bình đẳng có thể đã được thực hiện mà thậm chí không cần gọi một so sánh.

Đặc biệt là đối với nhiều trường hợp liệt kê các kích thước, phần lớn thời gian sẽ khác nhau. Hơn nữa, hầu hết các triển khai Java List đều có hiệu suất O (1) size() (thậm chí LinkedList, giữ kích thước của nó trong bộ nhớ cache).

Có lý do chính đáng để triển khai mặc định này không?

Trả lời

12

Hoạt động của phương thức bằng được chỉ định chi tiết và yêu cầu hành vi O (n). Trong khi điều này có thể là tối ưu cho các lớp con có phương thức kích thước là O (1), đối với một số lớp con, kích thước có thể là O (n) và hành vi được yêu cầu thực sự là sự xuống cấp. Trong mọi trường hợp, thông số rõ ràng và thay đổi này không thể thực hiện được .

Lưu ý rằng một phân lớp có thể ghi đè bằng nếu muốn, chèn kích thước so sánh khi thích hợp.

Reference.

+3

Vì vậy, nếu hiểu rõ, đó là không hiệu quả bởi vì nó đã được ghi nhận như vậy? :) –

+3

@Laurent Không phải vì "nó đã được ghi nhận như vậy", vì quyết định thiết kế với lý do là "đối với một số lớp con, phương pháp kích thước có thể là O (n) và hành vi được yêu cầu thực sự sẽ là một sự xuống cấp" :) –

+2

Tôi hiểu, nhưng làm giảm hiệu suất ở nơi đầu tiên cho tất cả việc thực hiện vì "một số trong số họ" có thể chậm hơn không có vẻ là một quyết định tốt cho tôi. Tôi đã thực hiện một mức tối ưu bằng cho O (1) danh sách có kích thước, và un-tối ưu hóa cho phần còn lại. Đặc biệt là đối với ArrayList là một workhorse trong Java ... –