Polb
Polb

Reputation: 700

HashSet addAll method modifies class internal field

I have a class which extends a parametrized version of HashSet. This class has an internal field currentSize which keeps track of how many elements have been added so far. The child class overrides the base class' add and addAll methods so the currentSize increases accordingly. My problem is that inside addAll, the size of the set is added two times to the currentSize counter, not once. Below is my class' code:

public class InheritHashSet extends HashSet<Integer> {
    private int currentSize = 0;

    @Override
    public boolean add(Integer e) {
        currentSize++;
        super.add(e);
    }

    @Override
    public boolean addAll(Collection<? extends Integer> e) {
        currentSize += e.size();
        super.addAll(e);
    }

    public int getCurrentSize() {
        return currentSize;
    }
}

The add method seems to be working fine, since after adding three elements, currentSize is 3, but the following will add 6 to the currentSize instead of 3:

InheritHashSet ihs = new InheritHashSet();
Collection<Integer> c = new LinkedList<Integer>();
c.add(new Integer(0));
c.add(new Integer(1));
c.add(new Integer(2));
ihs.addAll(c);
System.out.println(ihs.getCurrentSize()); // prints 6 instead of 3

It looks like the call to super.addAll(e) also modifies the currentSize (this does not seem to make any sense at all).

Upvotes: 3

Views: 812

Answers (2)

user6904265
user6904265

Reputation: 1938

The addAll() method of the InheritHashSet class first set currentSize = 3, with currentSize += e.size(); instruction. Then super.addAll(e); calls add(e) method three times. For dynamic binding the public boolean add(Integer e) of class InheritHashSet is invoked first and then currentSize is then incremented to 6.

for this reason you should implement addAll method in this way:

@Override
public boolean addAll(Collection<? extends Integer> e) {
    return super.addAll(e);
}

Upvotes: 2

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298898

It's almost never a good idea to extend an existing collection class, specifically when you are trying to enforce a new contract.

I would recommend you redesign your class to have a HashSet field rather than extend HashSet.

Read Effective Java by Joshua Bloch Item 16: Favor Composition over Inheritance.

Upvotes: 2

Related Questions