Problem: Make a Card Orderable

A Card has a rank and a suit. The rank is a number from 2 to 14, where 11 through 14 stand for J, Q, K, and A. The suit is one of the characters 'C', 'D', 'H', 'S', standing for Clubs, Diamonds, Hearts, and Spades. Here is the starting point. It has the two fields, a constructor, and getters, and nothing else.

public class Card {
  private int rank;
  private char suit;

  public Card(int rank, char suit) {
    this.rank = rank;
    this.suit = suit;
  }

  public int getRank() {
    return rank;
  }

  public char getSuit() {
    return suit;
  }
}

As the class stands, two sevens of diamonds built separately are not equal. A hand of cards cannot be sorted either. And there is no second ordering available. So we add three things:

  • Value equality — two cards are the same card when their rank and suit match (equals and hashCode).
  • A natural order — cards are ordered by rank, then by suit (Comparable).
  • A second order — a Comparator that orders by suit, then by rank within a suit, without changing Card.

A working solution is provided in the accompanying code for this practice problem, in the practice package (Card.java, SuitComparator.java). Run scripts/run.sh to see it sort a hand two different ways.

Steps

  1. Solution: Value Equality
  2. Solution: A Natural Order
  3. Solution: A Second Order