Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor changes (replaced "Java" with Credit Card Test Number)

...

This noncompliant code example associates credit card numbers with strings using a HashMap and subsequently attempts to retrieve the string value associated with a credit card number. The expected retrieved value is Java 4111111111111111; the actual retrieved value is null. The cause of this erroneous behavior is that the CreditCard class overrides the equals() method but fails to override the hashCode() method. Consequently, the default hashCode() method returns a different value for each object, even though the objects are logically equivalent; these differing values lead to examination of different hash buckets, which prevents the get() method from finding the intended value.

Code Block
bgColor#FFCCCC
public final class CreditCard {
  private final int number;

  public CreditCard(int number) {
    this.number = (short) number;
  }

  public boolean equals(Object o) {
    if (o == this) {
      return true;
    } 
    if (!(o instanceof CreditCard)) {
      return false;
    }
    CreditCard cc = (CreditCard)o;
    return cc.number == number; 
  }

  public static void main(String[] args) {
    Map<CreditCard, String> m = new HashMap<CreditCard, String>();
    m.put(new CreditCard(100), "Java4111111111111111");
    System.out.println(m.get(new CreditCard(100)));  
  }
}

...

Code Block
bgColor#ccccff
import java.util.Map;
import java.util.HashMap;

public final class CreditCard {
  private final int number;
  
  public CreditCard(int number) {
    this.number = (short) number;
  }

  public boolean equals(Object o) {
    if (o == this) {
      return true;
    } 
    if (!(o instanceof CreditCard)) {
      return false;
    }
    CreditCard cc = (CreditCard)o;
    return cc.number == number; 
  }

  public int hashCode() {
    int result = 7;
    result = 37 * result + number;
    return result;
  }

  public static void main(String[] args) {
    Map<CreditCard, String> m = new HashMap<CreditCard, String>();
    m.put(new CreditCard(100), "Java4111111111111111");
    System.out.println(m.get(new CreditCard(100)));
  }
}

...