2013-09-23 5 views
14

Seltsamer den Standard JDK 6 Implementierung von AbstractList::equals()nicht erst zu prüfen scheint, wenn die beiden Listen die gleiche Größe haben:JDK-Implementierung von AbstractList :: equals() überprüft nicht für Listengröße Gleichheit ersten

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

Wenn beide Listen viele Elemente enthalten oder Elemente, die Zeit zum Vergleichen benötigen, werden alle verglichen, bevor erkannt wird, dass eine Liste kürzer ist als die andere. Das scheint mir wirklich ineffizient zu sein, da die Gleichheit ohne einen einzigen Vergleich zustande gekommen wäre.

Insbesondere, dass für viele Situationen Listen Größen würden die meiste Zeit unterscheiden. Darüber hinaus haben die meisten Java List Implementierungen O (1) size() Performance (sogar LinkedList, die ihre Größe im Cache behalten).

Gibt es einen guten Grund für diese Standardimplementierung?

Antwort

12

Der Betrieb der Gleichheits Methode wird im Detail angegeben, und es erfordert das O (n) Verhalten. Obwohl dies für Unterklassen, deren Größenmethode O (1) ist, möglicherweise suboptimal ist, kann für einige Unterklassen die Methode der Größe selbst O (n) sein, und das angeforderte Verhalten wäre tatsächlich . In jedem Fall ist die Spezifikation klar und diese Änderung kann nicht vorgenommen werden.

Beachten Sie, dass eine Unterklasse bei Bedarf den Wert "equals" überschreiben kann, indem Sie bei Bedarf einen Vergleich der Größe einfügen.

Reference.

+3

Also, wenn gut zu verstehen, es ist ineffizient, weil es als solches dokumentiert ist? :) –

+3

@Laurent Nicht wegen "es wurde als solches dokumentiert", wegen der Designentscheidung mit dem Grund, dass "für einige Unterklassen die Größenmethode selbst O (n) sein könnte und das angeforderte Verhalten tatsächlich eine Verschlechterung wäre" :) –

+2

Ich verstehe, aber die Leistung an erster Stelle für die gesamte Implementierung zu verschlechtern, weil "einige von ihnen" langsamer sein könnten, scheint mir keine gute Entscheidung zu sein. Ich hätte ein optimiertes Equal für O (1) große Listen und für den Rest unoptimiert gemacht. Speziell für ArrayList, die ein Arbeitspferd in Java ist ... –

Verwandte Themen