2013-09-23 3 views
14

Stranamente il JDK 6 implementazione predefinita di AbstractList::equals()non sembra controllare prima se le due liste hanno la stessa dimensione:implementazione JDK di AbstractList :: equals() non controlla la lista uguaglianza misura desiderata

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

Se entrambi gli elenchi contengono molti articoli o elementi che richiedono tempo per il confronto, li confronteranno tutti prima di rendersi conto che una lista è più corta dell'altra; che mi sembra davvero inefficace in quanto l'uguaglianza potrebbe essere stata fatta senza nemmeno chiamare un confronto.

Soprattutto se per un sacco di situazioni le dimensioni delle liste differiscono la maggior parte delle volte. Inoltre, la maggior parte delle implementazioni Java List hanno prestazioni O (1) size() (anche LinkedList, che mantiene le sue dimensioni nella cache).

C'è una buona ragione per questa implementazione predefinita?

risposta

12

Il funzionamento del metodo equals è specificato in dettaglio, e richiede O (n) comportamento. Anche se questo potrebbe non essere ottimale per le sottoclassi il cui metodo di dimensione è O (1), per alcune sottoclassi il metodo può essere esso stesso O (n) e il comportamento richiesto sarebbe in realtà uno degrado. In ogni caso la specifica è chiara e questo cambiamento non può essere effettuato .

Si noti che una sottoclasse può eseguire l'override se necessario, inserendo un confronto di dimensioni quando appropriato.

Reference.

+3

Quindi, se a capire bene, è inefficiente perché è stato documentato come tale? :) –

+3

@Laurent Non a causa di "è stato documentato come tale", a causa della decisione di progettazione con il motivo di essere "per alcune sottoclassi il metodo di dimensioni potrebbe essere O (n) e il comportamento richiesto sarebbe in realtà un degrado" :) –

+2

Capisco, ma degrado le prestazioni al primo posto per tutte le implementazioni perché "alcune di esse" potrebbero essere più lente non sembra una buona decisione per me. Avrei creato un uguaglianza ottimizzata per gli elenchi di dimensioni O (1) e non ottimizzato per il resto. Soprattutto per ArrayList che è un cavallo di battaglia in Java ... –

Problemi correlati