问题
I am making a card related application.
Suits are ranked Clubs, Diamonds, Spades, Hearts
I'd like to order them like this:
Within the cards, Ace is the highest, and 2 is the lowest, so the standard Ace King Queen Jack order will be fine.
I'm trying to use the compareTo method.I don't understand it...at all.
I'm a visual learner, so code examples, like a step by step walkthrough of how to use the method would -really- help me out. It doesn't have to be related to my code, anything that I can study and try to implement by learning it visually will help at this point.
Here's my code so far. If someone could show me -where- exactly i should implement this, that would also help.
import java.util.Arrays;
public class PlayingCard implements Comparable {
// Class Constants
public static final int ACE = 1;
public static final int KING = 13;
public static final int QUEEN = 12;
public static final int JACK = 11;
public static final String SPADES = "spades";
public static final String CLUBS = "clubs";
public static final String HEARTS = "hearts";
public static final String DIAMONDS = "diamonds";
// Instance Variables
private int rank;
private String suit;
// Constructor
public PlayingCard () {
this.rank = PlayingCard.QUEEN;
this.suit = PlayingCard.SPADES;
}
public PlayingCard (int rank, String suit) {
this.rank = rank;
this.suit = suit;
Arrays.sort();
}
// Mutators
public void setRank (int rank) {
this.rank = rank;
}
public void setSuit (String suit) {
this.suit = suit;
}
// Accessors
public int getRank () {
return this.rank;
}
public String getSuit () {
return this.suit;
}
public String toString () {
return PlayingCard.rankToString(this.rank) + " of " + this.suit;
}
//Class Method
public static String rankToString(int rank) {
switch (rank) {
case(1): return "Ace";
case(2): return "two";
case(3): return "three";
case(4): return "four";
case(5): return "five";
case(6): return "six";
case(7): return "seven";
case(8): return "eight";
case(9): return "nine";
case(10): return "ten";
case(11): return "Jack";
case(12): return "Queen";
case(13): return "King";
}
return "INVALID";
}
public static void main(String [] args) {
// Generate an array of playing cards
PlayingCard [] deck = new PlayingCard[52];
String [] suits = {PlayingCard.CLUBS, PlayingCard.DIAMONDS, PlayingCard.SPADES, PlayingCard.HEARTS};
for(int i = 0; i < suits.length; i++) { // Run through each suit
for (int j = 0; j < 13; j++) { // Make each card
deck[i*13 + j] = new PlayingCard(j+1, suits[i]);
}
}
// Shuffle cards
for(int i = 0; i < deck.length; i++) {
int newPos = (int)(Math.random()*52);
PlayingCard temp = deck[i];
deck[i] = deck[newPos];
deck[newPos] = temp;
}
// Print out cards
System.out.println("Shuffled Deck");
for(int i = 0; i < deck.length; i++) {
System.out.println(deck[i]);
}
// Sort the deck
Arrays.sort(deck);
// Print out cards
System.out.println("\n\nSorted Deck");
for(int i = 0; i < deck.length; i++) {
System.out.println(deck[i]);
}
}
}
回答1:
Here's an example for compareTo
for the Integer
class:
public int compareTo(Object o) {
return this.value - ((Integer)o).value;
}
This is not the actual implementation, because if you are dealing with a small negative number and a large positive number, the result could overflow. However, this method is sufficient in many cases, including the OP's.
This subtracts the int
value of this object and the int
value of the other object. Think about why this works:
- If the two numbers are equal, the subtraction yields 0, so the numbers are understood to be equal.
- If
this
is greater thano
, the subtraction yields a positive value, sothis
is understood to be greater. - If
this
is less thano
, the subtraction yields a negative value, soo
is understood to be greater.
To help with this numeric method, you should probably give the suits integer values ranked in the appropriate order instead of string values, and define ACE
to be 14
instead of 1
, because the ace is greater than the king, which is 13
. With this, you can write a method that combines two comparing strategies:
public int compareTo(Object o) {
PlayingCard other = (PlayingCard) o;
int result = this.suit - other.suit;
if (result != 0)
return result;
return this.rank - other.rank;
}
This will first compare the suits, and if they are the same, it will compare the ranks.
You must place the compareTo
method in the PlayingCard
class, or it will not compile if you implement Comparable
.
回答2:
The suit and rank should be implemented with enumerators. Also it would be easier to read the code if you used two classes; a deck class and a card class.
I remade the program with enumerators and two classes:
public enum Suit {
Hearts("H"), Spades("S"), Clubs("C"), Diamonds("D");
private final String shortName;
private Suit(String shortName) {
this.shortName = shortName;
}
public String getShortName() {
return shortName;
}
}
public enum Rank {
King("K"), Queen("Q"), Jack("J"), Ten("10"), Nine("9"), Eight("8"), Seven("7"), Six("6"), Five("5"), Four("4"), Three("3"), Two("2"), Ace("E");
private final String shortName;
private Rank(String shortName) {
this.shortName = shortName;
}
public String getShortName() {
return shortName;
}
}
public class PlayingCard implements Comparable<PlayingCard> {
private Suit suit;
private Rank rank;
public PlayingCard(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
public String getShortName() {
return suit.getShortName() + rank.getShortName();
}
public String toString() {
return rank + " of " + suit;
}
public Suit getSuit() {
return suit;
}
public Rank getRank() {
return rank;
}
@Override
public int compareTo(PlayingCard other) {
// First compares the ranks and if they're equal the cards are sorted
// by their suits. The rank and suit are always sorted in the order
// they're declared in the enumerators.
if(rank.compareTo(other.getRank()) == 0) {
return suit.compareTo(other.getSuit());
} else {
return rank.compareTo(other.getRank());
}
}
}
public class Deck {
private ArrayList<PlayingCard> deck = new ArrayList<PlayingCard>();
public Deck() {
for(Suit s : Suit.values()) {
for(Rank r : Rank.values()) {
deck.add(new PlayingCard(s, r));
}
}
}
public void shuffle() {
Collections.shuffle(deck);
}
public void sort() {
Collections.sort(deck);
}
public void addToBottom(PlayingCard c) {
deck.add(c);
}
public PlayingCard removeTopCard() {
return deck.remove(0);
}
public PlayingCard peekTop() {
return deck.get(0);
}
public boolean isEmpty() {
return deck.isEmpty();
}
public String toString() {
StringBuilder sb = new StringBuilder();
for(PlayingCard c : deck) {
sb.append(c.getShortName() + ' ');
}
return sb.toString();
}
public static void main(String[] args) {
Deck deck = new Deck();
System.out.println(deck);
deck.shuffle();
System.out.println(deck);
deck.sort();
System.out.println(deck);
System.out.println(deck.peekTop());
}
}
The code creates a deck, shuffles it and sorts it. It prints the deck after each operation. Finally it prints the top card of the deck. An example output from main() is:
HK HQ HJ H10 H9 H8 H7 H6 H5 H4 H3 H2 HE SK SQ SJ S10 S9 S8 S7 S6 S5 S4 S3 S2 SE CK CQ CJ C10 C9 C8 C7 C6 C5 C4 C3 C2 CE DK DQ DJ D10 D9 D8 D7 D6 D5 D4 D3 D2 DE
D7 CE C8 C5 C9 DE SK H7 DQ DK D3 C7 C4 D2 D5 C6 S3 H10 S10 D10 S4 SJ D6 CQ CK D4 H8 H9 S6 HJ HE S8 S7 DJ C10 S2 SQ CJ HK C2 H2 C3 H5 H3 HQ D9 H6 S9 S5 SE H4 D8
HK SK CK DK HQ SQ CQ DQ HJ SJ CJ DJ H10 S10 C10 D10 H9 S9 C9 D9 H8 S8 C8 D8 H7 S7 C7 D7 H6 S6 C6 D6 H5 S5 C5 D5 H4 S4 C4 D4 H3 S3 C3 D3 H2 S2 C2 D2 HE SE CE DE
King of Hearts
来源:https://stackoverflow.com/questions/18041502/what-variables-do-i-have-to-compare-in-this-java-code