SWE 619 In Class Exercise Number 10A
November 14, 2017


Consider Bloch's InstrumentedHashSet, InstrumentedSet, and ForwardingSet examples:
public class InstrumentedHashSet<E> extends HashSet<E>{
   private int addCount = 0;	
   public InstrumentedHashSet() {}

   @Override public boolean add(E e){ 
      addCount++; 
      return super.add(e); 
   }
   @Override public boolean addAll(Collection<? extends E> c){ 
       // What to do with addCount?
       return super.addAll(c); 
   }
   public int getAddCount(){ return addCount; }
}
public class InstrumentedSet<E> extends ForwardingSet<E>{
   private int addCount = 0;	

   public InstrumentedSet(Set<E> s){ super(s); }
   @Override public boolean add(E e){ addCount++; return super.add(e); }
   public int getAddCount(){ return addCount; }
}
public class ForwardingSet<E> implements Set<E> {
   private final Set<E> s;

   public ForwardingSet(Set<E> s){ this.s = s; }
   public           boolean add(E e)        { return s.add(e);     }
   public           boolean remove(Object o){ return s.remove(o);  }
   @Override public boolean equals(Object o){ return s.equals(o);  }
   @Override public boolean hashCode()      { return s.hashCode(); }
   @Override public String  toString()      { return s.toString(); }
   // Other forwarded methods from Set interface omitted
}
Consider also the following client code:
   Set<String> r = new HashSet<String>();
   r.add("ant"); r.add("bee");

   Set<String> sh = new InstrumentedHashSet<String>();
   sh.addAll(r);

   Set<String> s =  new InstrumentedSet<String>(r);
   s.add("ant"); s.add("cat");

   Set<String> t = new InstrumentedSet<String>(s);
   t.add("dog");

   r.remove("bee");
   s.remove("ant");

  1. How do you think the addCount variable should be updated in the addAll() method in InstrumentedHashSet?


    • Why is this a hard question?


    • What does the answer say about inheritance?


    • Does equals() behave correctly in InstrumentedHashSet?


  2. Given your previous answer, what is the value of sh.addCount at the end of the computation?


  3. Consider the InstrumentedSet solution. Besides being correct (always a plus!) why is it more general than the InstrumentedHashSet solution?


  4. At the end of the computation, what are the values of: r, s, and t?


  5. What would a call to s.getAddCount() return at the end of the computation?


  6. At the end of the computation, what are the values of: r.equals(s), s.equals(t), and t.equals(s)?


    • Are there any problems with the equals() contract?


  7. Would this still work if you globally replaced sets with lists?


  8. Would this still work if you globally replaced sets with collections?


Note: There is a lot going on in this example. I highly recommend that you play with the code until you understand it.