Почему основная функция возвращает неожиданный результат выполнения?

Я пытаюсь понять исходный код:

public class InstrumentedSet extends HashSet {
    // Keeps the number of attempted element insertions

    private int addCount;

    public InstrumentedHashSet(Collection c) {
        super(c);
    }

    public boolean add(Object o) {
      addCount++;
      return super.add(o);
    }

    public boolean addAll(Collection c) {
      addCount += c.size();
      return super.addAll(c);
    }

    public int getAddCount() {
      return addCount;
    }

    public static void main(String[] args) {
      InstrumentedHashSet s = new InstrumentedHashSet();
      String s1[] = new String[] {"Snap","Crackle","Pop"};
      s.addAll(Arrays.asList(s1));
      System.out.println(s.getAddCount());
      }
    }
}

Я не могу понять, почему основная функция возвращает значение выполнения 6 вместо возвращаемого значения 3.

2 ответа

Решение

Ну, кроме того факта, что ваш текущий код не компилируется, можно объяснить это поведение.

Ты звонишь addAll на вашем новом InstrumentedHashSet (или же InstrumentedSet) и этот метод выглядит следующим образом:

addCount += c.size();
return super.addAll(c);

Сначала вы добавляете 3 к addCount и поскольку эта переменная была 0 раньше, она также будет равна 3.
Тогда ты звонишь addAll из super учебный класс HashSet и реализация выглядит так:

public boolean addAll(Collection<? extends E> c) {
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
}

Наиболее важной частью является if заявление: if (add(e)), Это вызывает add за каждый элемент в пройденном Collection и поскольку вы переопределили этот метод своей собственной реализацией:

public boolean add(Object o) {
    addCount++;
    return super.add(o);
}

... этот метод будет вызываться вместо родительской реализации. И вот вы увеличиваете addCount для каждого добавленного элемента. Итак, теперь вы подсчитываете каждый элемент во второй раз.
И это в основном причина, почему System.out.println(s.getAddCount()); печатает удвоенное количество пройденных Collection от Arrays.asList(s1),

Это потому HashSetс реализацией addAll вызовы методов add метод и из-за полиморфизма, InstrumentedSet.add называется.

Удалить addCount += c.size(); от InstrumentedSet.addAll реализация, и это будет работать.

Другие вопросы по тегам