2016-02-22 7 views
13

ArrayList erbt equals Implementierung von seiner Elternklasse AbstractList, die nicht sehr effektiv ist.Warum überschreibt ArrayList nicht gleich() für bessere Leistung?

Es könnte zuerst die Größe der beiden ArrayLists überprüfen und dann false sofort zurückgeben, wenn diese Größen unterschiedlich sind. Warum macht ArrayList das nicht?

+0

Versuchen Sie diesen Thread lesen http://programmers.stackexchange.com/questions/239139/why-do-arrays-in-java-not-override-equals –

+1

ich glaube nicht, dass [diese ] (http://stackoverflow.com/questions/18958113/jdk-implementation-of-abstractlistequals-does-not-check-for-lists-size-equali) Frage ist ein Duplikat, für Wiedereröffnung gewählt. – Maroun

Antwort

7

Wie in this answer erwähnt, geschieht dies nicht, weil einige Implementierungen O (n) Komplexität ihrer size Methode hat, so kann dies in der Tat ein Abbau sein.

Ich bin damit einverstanden, dass equals konsistent in allen Listen machen Implementierungen Sammlungen beeinflussen kann, die O (1) Größe Komplexität hat, aber vielleicht Java-Entwickler gedacht, dass es viel ist einfacher es einzulegen, wenn Sie benötigen, als es zu entfernen, wenn Sie don‘ t (Sie müssen die gesamte Methode neu implementieren!). Zum Beispiel können Sie einfach diese Optimierung mit so etwas wie hinzufügen:

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

Aber wenn es ursprünglich mit der Größe Prüfung (in der abstrakten Klasse) umgesetzt wurde, mußte man das ganze Verfahren neu implementieren und die Größe entfernen Check:

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, was ich vermisst habe, als ich darüber nachdachte - während die Standardimplementierung von 'size()' 'O (1)' ist, ist es nicht 'final', also kann man nicht garantieren, dass es nicht überschrieben wurde. Obvs. –

+0

Vielleicht bin ich noch nicht wach, aber ... könnte man nicht einfach 'return super.equals (o);' anstatt manuell die Iteration machen? – Marco13

Verwandte Themen