SWE/CS 332 In Class Exercise # 10


Name(s):

Consider the GrowList example:
//  GrowList is a mutable list that only gets longer.
public class GrowList <E> {

  private Map<Integer,E> values;

  // return an empty list
  public GrowList() { values = new HashMap<>(); }
 
  // add to the end of the list
  public void add(E o) {
     values.put(size(), o);
  }

  // number of values in list
  public int size() { return values.size(); }

  // get ith value in list
  // @throw IOOBE if index out of range
  public E get(int i) { 
     if (! inRange(i)) throw new IndexOutOfBoundsException("GrowList.get");
     return values.get(i);
  }

  // update ith value in list;  return previous value
  // @throw IOOBE if index out of range
  public E set(int i, E o) {
     if (! inRange(i)) throw new IndexOutOfBoundsException("GrowList.set");
     return values.put(i, o);
  }
  
  // private helper method
  private boolean inRange(int i) { return (i >= 0) && (i < size()); }
  }
}

The abstraction function is that the indices in the GrowList are exactly the keys in the map, and the list element for each index is simply the associated value in the map. In other words the AF is:

[values.get(0), values.get(1), ... values.get(values.size()-1)]

One possible rep-invariant is that the map isn't null and the keyset of the map is exactly the integers 0..values.size()-1

  1. Is that enough? Let's find out!
    • Analyze each method with respect to the rep-invariant. Which method(s) require(s) the most attention?
    • Repeat the exercise for the contracts. Which method(s) require(s) the most attention?


  2. Identify some rep states that don't satisfy the rep-invariant. How do the broken rep-invariants affect the behavior of the methods?

  3. Consider a method
        public void nasty() {
    
    
    
        }
    
    that breaks the representation invariant. What are some simple implementations for nasty()?

    Does the presence of nasty() affect the correctness of the other methods in GrowList?

  4. Consider the constraint that the list only grows.
    • Is this part of the implementation or part of the abstraction?
    • Is it possible to capture this constraint with an invariant? Why or why not?