2015-06-07 2 views
0

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

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

Зачем ему возвращаться 3? –

+0

Потому что мы итерируем 3 строки. –

+2

Где вы ссылаетесь на 3 строки и что это имеет отношение к счету? –

ответ

1

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

Вы звоните addAll на новом InstrumentedHashSet (или InstrumentedSet), например, и этот метод выглядит следующим образом:

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

Сначала вы добавляете 3 к addCount и так, что переменная была 0 до, он будет то и 3.
Затем вы вызываете addAll из super класса HashSet и the implementation of it выглядит следующим образом:

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 и так как вы overriden, что метод с вашей собственной реализации:

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

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

1

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

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