Почему основная функция возвращает неожиданный результат выполнения?
Я пытаюсь понять исходный код:
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
реализация, и это будет работать.