SWE 619 In Class Exercise Number 13


How well are you prepared for the final? This exercise should help you find out. Piazza discussions encouraged!
public class Stack {
   private Object[] elements; private int size = 0;

   public Stack() { this.elements = new Object[0]; }

   public void push (Object e) {
     if (e == null) throw new NullPointerException("Stack.push");
     ensureCapacity(); elements[size++] = e;  
   }

   public void pushAll (Object[] collection) { for (Object obj: collection) { push(obj); } }

   public Object pop () {
     if (size == 0) throw new IllegalStateException("Stack.pop");
     Object result = elements[--size];
     // elements[size] = null;
     return result;
   }

   @Override public String toString() {
      String result = "size = " + size;
      result += "; elements = [";
      for (int i = 0; i < elements.length; i++) {
         if (i < elements.length-1)
            result = result + elements[i] + ", ";
         else
            result = result + elements[i];
      }
      return result + "]";
   }
}
  1. Write a contract for push(Object e).

  2. What is wrong with toString()? Fix it.

  3. What rep-invariant is likely broken? Fix it.

  4. How would Bloch's Item 25: Prefer Lists to Arrays apply here? Would it make the rep-invariant simpler?

  5. How would you argue that that pop() is correct (or not)?

  6. As Stack is written, pushAll() requires special documention? Why? What would Bloch suggest as an alternative?

  7. Would it be possible to override equals() and have it satisfy its contract? How about implementing the Comparable interface?

  8. Generify. What should happen to the parameter for pushAll()? Why?

  9. Suppose we decide to implement the Cloneable() interface. In what ways would Bloch think we would likely get it wrong? What would Bloch recommend instead?