Reputation: 96
I can't figure out how to properly use the Comparator interface.
NOTE: I don't want to use the "one line" comparator implementation I see on most code, meaning :
Collections.sort(deck, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return WHATEVER;
});
Again, I don't want to use this, because I'm going to be sorting many different ArrayLists and it seems like a waste of space to do that every time. I want to somehow make it work, having my compareTo method written once in one place.
I tried many different things, but I'm new to implementing interfaces, so I'm probably missing something.
This is my Card class with it's compare method. (NOTE: Let me save you some time and say that I'm not interested in using Enumerations to simplify the code and the comparison, I just want to learn how to use Comparator properly. I know it looks bad but I have to use some already written code. )
import java.util.*;
public class Card implements Comparator<Card>
{
private String number;
private int value;
private int finalValue;
private String suit;
private Player owner;
public Card(String number, String suit)
{
this.number=number;
switch (number){
case "2": this.value = 2;
break;
case "3": this.value = 3;
break;
case "4": this.value = 4;
break;
case "5": this.value = 5;
break;
case "6": this.value = 6;
break;
case "7": this.value = 7;
break;
case "8": this.value = 8;
break;
case "9": this.value = 9;
break;
case "10": this.value = 10;
break;
case "J": this.value = 11;
break;
case "Q": this.value = 12;
break;
case "K": this.value = 13;
break;
case "A": this.value = 14;
break;
}
this.suit=suit;
switch (suit){
case "Spades": this.finalValue = this.value*4;
break;
case "Hearts": this.finalValue = this.value*5;
break;
case "Clubs": this.finalValue = this.value*2;
break;
case "Diamonds": this.finalValue = this.value*3;
break;
}
}
public int compare(Card card1, Card card2)
{
Integer suitValue1;
if (card1.getSuit() == "Hearts")
suitValue1=5;
else if (card1.getSuit() == "Spades")
suitValue1=4;
else if (card1.getSuit() == "Diamonds")
suitValue1=3;
else
suitValue1=2;
Integer suitValue2;
if (card2.getSuit() == "Hearts")
suitValue2=5;
else if (card2.getSuit() == "Spades")
suitValue2=4;
else if (card2.getSuit() == "Diamonds")
suitValue2=3;
else
suitValue2=2;
Integer value1, value2;
value1 = card1.getValue();
value2 = card2.getValue();
if (suitValue1 != suitValue2)
return suitValue1.compareTo(suitValue2);
else
return value1.compareTo(value2);
}
//get methods
public int getValue()
{return this.value;}
public int getFinalValue()
{return this.finalValue;}
public String getNumber()
{return this.number;}
public String getSuit()
{return this.suit;}
public Player getOwner()
{return this.owner;}
//set methods
public void setValue(int value)
{this.value = value;}
public void setFinalValue(int finalValue)
{this.finalValue = finalValue;}
public void setNumber(String number)
{this.number = number;}
public void setSuit(String suit)
{this.suit = suit;}
public void setOwner(Player player)
{this.owner = player;}
}
So that's my compare method. Should I put it in another class or something? I try to call it using this:
Collections.sort(deck, new Comparator<Card>());
but that is obviously wrong.
deck is an ArrayList : private ArrayList<Card> deck = new ArrayList<Card>();
filled with various Card objects.
Upvotes: 1
Views: 1178
Reputation: 617
i think this is what you intended. I don't believe you can use a switch statement on Strings unless you are 1.7+
public class Card implements Comparable<Card>
{
private String number;
private int value;
private int finalValue;
private String suit;
private Player owner;
public Card(String number, String suit)
{
this.number = number;
this.value = 0;
this.finalValue = 0;
//card value
if ("2".equalsIgnoreCase(number))
{
this.value = 2;
}
else if ("3".equalsIgnoreCase(number))
{
this.value = 3;
}
else if ("4".equalsIgnoreCase(number))
{
this.value = 4;
}
else if ("5".equalsIgnoreCase(number))
{
this.value = 5;
}
else if ("6".equalsIgnoreCase(number))
{
this.value = 6;
}
else if ("7".equalsIgnoreCase(number))
{
this.value = 7;
}
else if ("8".equalsIgnoreCase(number))
{
this.value = 8;
}
else if ("9".equalsIgnoreCase(number))
{
this.value = 9;
}
else if ("10".equalsIgnoreCase(number))
{
this.value = 10;
}
else if ("J".equalsIgnoreCase(number))
{
this.value = 11;
}
else if ("Q".equalsIgnoreCase(number))
{
this.value = 12;
}
else if ("K".equalsIgnoreCase(number))
{
this.value = 13;
}
else if ("A".equalsIgnoreCase(number))
{
this.value = 14;
}
//suits
if ("Spades".equalsIgnoreCase(number))
{
this.finalValue = this.value * 4;
}
else if ("Hearts".equalsIgnoreCase(number))
{
this.finalValue = this.value * 5;
}
else if ("Clubs".equalsIgnoreCase(number))
{
this.finalValue = this.value * 2;
}
else if ("Diamonds".equalsIgnoreCase(number))
{
this.finalValue = this.value * 3;
}
}
@Override
public int compareTo(Card o)
{
final int EQUAL = 0;
final int LESS_THAN = -1;
final int GREATER_THAN = 1;
if (this == o || this.getFinalValue() == o.getFinalValue())
{
return EQUAL;
}
else if (this.getFinalValue() < o.getFinalValue())
{
return LESS_THAN;
}
else
{
return GREATER_THAN;
}
}
// get methods
public int getValue()
{
return this.value;
}
public int getFinalValue()
{
return this.finalValue;
}
public String getNumber()
{
return this.number;
}
public String getSuit()
{
return this.suit;
}
public Player getOwner()
{
return this.owner;
}
// set methods
public void setValue(int value)
{
this.value = value;
}
public void setFinalValue(int finalValue)
{
this.finalValue = finalValue;
}
public void setNumber(String number)
{
this.number = number;
}
public void setSuit(String suit)
{
this.suit = suit;
}
public void setOwner(Player player)
{
this.owner = player;
}
}
Upvotes: -1
Reputation: 30310
You are confusing Comparable
with Comparator
. They are similar of course but really fundamentally different.
Comparable
defines the natural ordering of a class--how instances of your class should sort themselves by default. That's actually what you want here.
Comparator
helps you to sort the instances of your class when you want to use a different sort order than the natural order. That doesn't seem to be your aim here.
So what you actually want is this:
public class Card implements Comparable<Card> {
public int compareTo(Card otherCard) {
//return 1 when this instance is greater than the parameter, -1 if less; 0 if equal
}
//Other stuff
//And make sure compareTo is consistent with equals
}
Note that the method you have to implement is compareTo
, which is different from what you implement with Comparator
.
Then you simply sort this way:
Collections.sort(deck)
And the cards will know how to sort themselves.
If you need more guidance, we actually did a tutorial on Comparable
and Comparator
with the files available on Github. Check it out if you like.
Upvotes: 4
Reputation: 1039
I agree with Juned, use value1.equals(value2) this returns a boolean. From the looks of things you only doing string comparison which is fairly stright forward.
Good luck.
Upvotes: 0
Reputation: 11
To summarize:
Upvotes: 1
Reputation: 7743
You want to implement Comparable, and then you can just sort the array.
Upvotes: 0
Reputation: 4092
Since you seem to have one only way to compare Card objects, you don't really have to use a Comparator. Let Card implement Comparable, instead, and then sort by the 1-parameter method:
Collections.sort(deck);
Upvotes: 1