2013-09-23 39 views
14

dziwne domyślny JDK 6 wdrożenie AbstractList::equals()nie wydaje się, by sprawdzić najpierw, czy dwie listy tego samego rozmiaru:JDK realizacja AbstractList :: equals() nie sprawdza listy pierwszej równości wielkości

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

Jeśli obie listy zawierają wiele elementów lub przedmiotów, których porównanie wymaga czasu, porównuje je wszystkie, zanim zorientuje się, że jedna lista jest krótsza od drugiej; co wydaje mi się naprawdę nieefektywne, ponieważ równość mogłaby zostać dokonana, nawet bez wołania o porównanie.

Zwłaszcza, że ​​w wielu sytuacjach rozmiary listy byłyby przez większość czasu różne. Ponadto większość implementacji Java List ma wydajność O (1) size() (nawet LinkedList, która zachowuje swój rozmiar w pamięci podręcznej).

Czy istnieje dobry powód tej domyślnej implementacji?

Odpowiedz

12

Operacja metody równości jest określona w szczegółach, a jej numer wymaga zachowania O (n). Chociaż może to być suboptymalne dla podklas o metodzie O (1), dla niektórych podklas metoda o rozmiarze może sama być O (n), a żądane zachowanie w rzeczywistości byłoby degradacją w postaci . W każdym razie specyfikacja jest jasna, a ta zmiana nie może być wykonana .

Należy zauważyć, że podklasa może zostać zastąpiona w razie potrzeby, wstawiając w razie potrzeby rozmiar o rozmiarze .

Reference.

+3

Więc jeśli dobrze rozumiem, to jest nieefektywne, ponieważ został udokumentowany jako taki? :) –

+3

@ Laurent Nie z powodu "zostało to udokumentowane jako takie", z powodu decyzji projektowej z powodu bycia "dla niektórych podklas metoda wielkości może sama być O (n), a żądane zachowanie byłoby de facto degradacją" :) –

+2

Rozumiem, ale obniżenie wydajności na pierwszym miejscu dla wszystkich realizacji, ponieważ "niektóre z nich" mogą być wolniejsze, nie wydaje mi się dobrą decyzją. Zoptymalizowałbym się dla list o rozmiarze O (1) i nie został zoptymalizowany dla reszty. Specjalnie dla ArrayList, który jest koniem roboczym w Javie ... –