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

Почему ArrayList не переопределяет equals() для лучшей производительности?

ArrayList наследует реализацию equals из своего родительского класса AbstractList, что не очень эффективно.

Сначала он может проверить размер двух ArrayLists, а затем вернуть false сразу, если эти размеры разные. Почему это не делает ArrayList?

4b9b3361

Ответ 1

Как отмечено в этом ответе, это не делается, потому что некоторые реализации имеют O (n) сложность их метода size, поэтому это может быть действительно деградация.

Я согласен с тем, что создание equals последовательного во всех реализациях списков может повлиять на коллекции с сложностью размера O (1), но, возможно, разработчики Java подумали, что гораздо проще вставить его, когда вам нужно, чем удалить его, когда вы этого не сделаете (вам придется повторно реализовать весь метод!). Например, вы можете легко добавить эту оптимизацию с чем-то вроде:

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

Но если он был первоначально реализован с проверкой размера (в абстрактном классе), вам пришлось повторно реализовать весь метод и удалить проверку размера:

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