Какой метод экземпляра вызывается, когда метод супертипа вызывает метод, представленный как в супертипе, так и в подтипе - PullRequest
0 голосов
/ 20 февраля 2019

Прошу прощения, если мне не хватает некоторого ядра Java здесь.

Я искал в javadocs HashSet спецификацию его реализации Collection.containsAll(), и она, очевидно, наследует реализацию от AbstractCollection который согласно документации JDK 8 выглядит следующим образом:

public boolean containsAll(Collection<?> c) {
    for (Object e : c)
        if (!contains(e))
            return false;
    return true;
}

Мой вопрос связан с тем фактом, что, хотя HashSet не переопределяет containsAll(), он переопределяетcontains():

public boolean contains(Object o) {
    return map.containsKey(o);
}

AbstractCollection аналогично:

public boolean contains(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
        while (it.hasNext())
            if (it.next()==null)
                return true;
    } else {
        while (it.hasNext())
            if (o.equals(it.next()))
                return true;
    }
    return false;
}

Насколько я понимаю, когда вызов члена экземпляра не указан явно в экземпляре, JVM неявно заменяет егос this.instanceMemberCall(), который в этом случае будет означать AbstractCollection s contains(), который вызывается.Но опять же Я прочитал здесь , что сложность времени для HashMap / HashSet * containsAll() будет O (n), предполагая, что HashSet * contains() (O (1)) называется.Был бы признателен за некоторую ясность относительно фактической семантики, стоящей за этим.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Это интересный вопрос.HashSet в Java поддерживается HashMap.Метод containsAll() просто зацикливается на contains(), в этом случае метод HashSet содержит.Это потому, что HashSet переопределяет contains и делегатов.

Поскольку HashSet поддерживается HashMap, фактический вызов containsKey(Object key).

containsKey(Object key) HashMap в основном дает вам O(1) сложность.Тем не менее, containsAll() делает цикл по n элементам.Ваша сложность в худшем случае становится O(n).

Причина, по которой я сказал, что это в основном , потому что производительность HashMap зависит от хеширования.

0 голосов
/ 20 февраля 2019

Нет, это просто полиморфизм.Всякий раз, когда метод вызывается для объекта, тип этого объекта true не имеет значения, ничего больше.

Значение: не имеет значения, что foo() реализован в Base.Когда foo() вызывает bar() с bar() переопределенным в Child.Если у вас есть дочерний объект, то всегда будет вызываться версия Child bar().

В вашем примере this - это не AbstractSet, это HashSet!

Или, другими словами, не имеет значения, «где» вызывается метод.Важно то, какой тип объекта вызывается.И как уже говорилось, ваш объект имеет тип HashSet!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...