Подтвердить что ты не робот

JDK-реализация AbstractList:: equals() не проверяет сначала равенство размера списка

Странно, что реализация JDK 6 по умолчанию AbstractList::equals() , по-видимому, не проверяет сначала, если два списка имеют одинаковый размер:

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 List имеют производительность O (1) size() (даже LinkedList, которые сохраняют свой размер в кеше).

Есть ли веская причина для этой реализации по умолчанию?

4b9b3361

Ответ 1

Операция метода equals подробно описана, и это требует поведения O (n). Хотя это может быть субоптимально для подклассы, размерный метод которых O (1), для некоторых подклассов размер метод может сам быть O (n), и запрошенное поведение фактически будет деградации. В любом случае спецификация понятна, и это изменение не может сделайте.

Обратите внимание, что подкласс может, если необходимо, переопределять равные значения, вставляя размер сравнение при необходимости.

Ссылка.