user3740970
user3740970

Reputation: 389

How to use the comparetor method to sort enum objects?

I have a Class Card and a Class Hand. I have also 2 enums:
Suit which contains the values: DIAMOND, CLUB, HEART, SPADE
and Rank containing the values: TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE

The Hand class has an arraylist which links to the Card class. I want to override the compareto() method in the Hand class so that the Card-objects are sorted by rank-values ​​in this order:

TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE in ascending order.

If there are 2 cards which have the same rank-value, then they should be sorted by the suit-values which is in this order:

DIAMOND, CLUB, HEART, SPADE in ascending order.

For example if one hand contains the cards: SPADE TWO, DIAMOND TWO, HEART ACE, CLUB NINE. Then it is supposed that when I call Collections.sort() on the arraylist which contains the cards, they should be printed in this order: DIAMOND TWO, SPADE TWO, CLUB NINE, HEART ACE.

The code in the compareto() method does not work at the moment.

public class Card implements Comparable<Object> {
private Suit suit;
private Rank rank;

public Card(Suit suit, Rank rank) {
    this.suit = suit;
    this.rank = rank;
}

public Suit getSuit() {
    return suit;
}

public void setSuit(Suit suit) {
    this.suit = suit;
}

public Rank getRank() {
    return rank;
}

public void setRank(Rank rank) {
    this.rank = rank;
}

@Override
public String toString() {
    return getSuit() + " " + getRank();
}

@Override
public int compareTo(Object otherObject) {
    Card other = (Card) otherObject;
    if (rank.TWO < other.rank.THREE) {
        return -1;
    }
    if (rank.TWO > other.rank.THREE) {
        return 1;
    }
    return 0;
}

}




public class Hand {
private ArrayList<Card> cards = new ArrayList<>();

public boolean add(Card c) {
    if (linearSearchList(cards, c) == false) { // if the card do NOT exist in the arraylist
        cards.add(c);
        return true;
    }
    return false;
}

public boolean remove(Card c) {
    if (linearSearchList(cards, c) == true) { // if the card already in the arraylist
        cards.remove(c);
        return true;
    }
    return false;
}

public ArrayList<Card> getCards() {
    return new ArrayList<>(cards);
}

public static boolean linearSearchList(ArrayList<Card> cardsList, Card c) {
    boolean found = false;
    int i = 0;
    while (!found && i < cardsList.size()) {
        if (cardsList.get(i).equals(c)) {
            found = true;
        } else {
            i++;
        }
    }
    if (found) {
        return true;
    } else {
        return false;
    }
}

@Override
public String toString() {
    Collections.sort(cards);

    return cards.toString();
}

}



public enum Suit {
DIAMOND, CLUB, HEART, SPADE;
}


public enum Rank {
TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE;

}



public class MainApp {

public static void main(String[] args) {
    Card c1 = new Card(Suit.DIAMOND, Rank.QUEEN);
    Card c2 = new Card(Suit.HEART, Rank.EIGHT);
    Card c3 = new Card(Suit.DIAMOND, Rank.KING);
    Card c4 = new Card(Suit.CLUB, Rank.TWO);
    Card c5 = new Card(Suit.SPADE, Rank.ACE);

    Hand hand1 = new Hand();
    hand1.add(c1);
    hand1.add(c2);
    hand1.add(c3);
    hand1.add(c4);
    hand1.add(c5);
    Collections.sort(hand1.getCards());

    for (Card card : hand1.getCards()) {
        System.out.println(card);
    }

}

}

Upvotes: 0

Views: 1731

Answers (1)

Mạnh Quyết Nguyễn
Mạnh Quyết Nguyễn

Reputation: 18235

First, make your class implements Comparable<Card>, use Object may introduce errors when you're attempting to compare to a random object:

public class Card implements Comparable<Card> {

You did not even provide a correct body for compareTo, hence it does not work. Later do not throws random code here please.

@Override
public int compareTo(Card otherCard) {
    if (this.rank == otherCard.rank) {
       return this.suite.compareTo(otherCard.suite);
    }
    return this.rank.compareTo(otherCard.rank);
}

Note that this implementation is depends on default enum order, which requires you specify ONE, TWO, THREE... in order in Rank enum and DIAMON, ... in Suite enum

If you want a custom compareTo for your enum, you must implement it separately.

Upvotes: 1

Related Questions