SWE 619 Quiz Number 10
November 9, 2011

Consider the following code.
class Apple {
  private String name;
  public Apple (String name) { this.name = name;}
  @Override public boolean equals (Object o) {
     if (!(o instanceof Apple)) { return false; }
     Apple a = (Apple) o;     
     // Note: I fixed this bug *after* the quiz.
     // If the bug (negatively) affected your solution, please see me
     // return name == a.name;        
     return name.equals(a.name);
  }
  @Override public int hashCode() { return name.hashCode(); }
  @Override public String toString() { return name; }
}
class StoreApple extends Apple {
  private int price;
  public StoreApple (String name, int price) { super(name); this.price = price;}
  @Override public boolean equals (Object o) { 
     if (! (o instanceof StoreApple)) { return false; }
     StoreApple sa = (StoreApple) o;             
     return super.equals(sa) && (price == sa.price);         
  }
  @Override public int hashCode() { return super.hashCode(); }
  @Override public String toString() { return super.toString() + " : " + price; }
}

// client code
Apple a = new StoreApple("Fuji", 79);
Apple b = new Apple     ("Fuji");
Apple c = new StoreApple("Fuji", 89);

Set<Apple> apples  = new HashSet<Apple>();
Set<Apple> oranges = new HashSet<Apple>();

 apples.add(a);  apples.add(b);
oranges.add(b); oranges.add(a);
  1. Is equals() symmetric? If not, give a counterexample using objects a, b, and/or c.
    Answer: No, equals() is not symmetric. (3 free points)
        a.equals(b);  // invokes the equals() in StoreApple; result is "false"
        b.equals(a);  // invokes the equals() in Apple; result is "true"
    
  2. Is equals() transitive? If not, give a counterexample using objects a, b, and/or c.
    Answer: Yes, it is transitive. (3 points) Grading note: Some students wished to reformulate the transitivity rule as:
    if b.equals(a) and b.equals(c) then a.equals(c)
    
    The point is that this isn't transitivity. Instead it's a mix of symmetry and transitivity - transisymmetry, if you like.
  3. What are the final values of the sets apples and oranges?
    Answer:
    apples  = [Fuji 79]
    oranges = [Fuji, Fuji 79]
    
    Grading note: Since you don't know which way the comparison is done inside the add() method of the HashSet class, it's also fine if you switched the values of these two sets. The point is that the sets are different.
  4. Does hashCode() satisfy its contract? Explain. Note that this is a question about correctness only.
    Answer: Yes, it does. Note that if two apples are equal (StoreApple or otherwise), they will have the same hash. Although the y component is not included in the hash, this is a performance issue, not a correctness issue. (3 points)