2013-09-23 21 views
14

奇怪的是默認的JDK 6實現AbstractList::equals()似乎並不首先檢查,如果兩個列表具有相同的大小JDK實現AbstractList中::平等的()不檢查列表大小相等第一

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

如果兩個列表都包含大量項目或需要時間進行比較的項目,那麼在比較所有項目之前,他們會意識到一個列表比另一個列表短;這對我來說似乎是非常低效的,因爲甚至可以在沒有比較的情況下進行平等。

特別是對於很多情況,列表大小大多數情況下會有所不同。此外,大多數Java實現具有O(1)size()性能(即使LinkedList,其大小保持在緩存中)。

這個默認實現有一個很好的理由嗎?

回答

12

等方法的操作在一定程度上被詳細說明,它需要O(n)行爲。儘管對於尺寸方法爲O(1)的 子類,這可能不是最佳的,但對於一些子類, 方法的大小本身可能是O(n),並且所請求的行爲實際上會是降級。在任何情況下,該規範都是明確的,並且此更改不能作出 。

請注意,如果需要,子類可能會覆蓋等於,在適當時插入大小 比較。

Reference.

+3

所以,如果很好地理解,這是低效的,因爲它已被記錄爲這樣? :) –

+3

@Laurent不是因爲「它被記錄爲這樣」,因爲設計決定的原因是「對於某些子類,size方法本身可能是O(n),並且所請求的行爲實際上會是一種降級」 :) –

+2

我明白了,但是在所有實施中首先降低了性能,因爲「其中一些」可能會變慢對我來說似乎不是一個好的決定。我會爲O(1)大小的列表做一個優化的平等,其餘的則不做優化。特別是對於ArrayList,它是Java中的主力... –