SWE/CS 332 In Class Exercise #24

Names:
Consider a (partial) variant of Bloch's Stack example:
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?

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

  6. pushAll() should have a more general type for its parameter. Why? What is it?

  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 pushAll()?