![](/img/trans.png)
[英]Collections.sort() works with Comparable or Comparator?
[英]Collections.sort, Enum, Comparable Interface problems
我有一个班级卡片,其他卡片(纸牌游戏)是从该卡片继承的。 卡套和号码存储在这样的枚举中
public static enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES
};
public static enum Rank {
DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
};
我的第一个问题是如何更改卡片等级的顺序。 在从类Card继承的每个单独的类(纸牌游戏)中,因为不同的纸牌游戏对不同的纸牌具有不同的重要性级别。
我的第二个问题是使用可比接口。
所以我有这样的班级卡:
public class Card implements Comparable<Card> {
public Suit suit;
public Rank rank;
public Card(Rank ranker, Suit suiter) {
rank = ranker;
suit = suiter;
}
//Other Methods for rank and suit here.
@Override
public int compareTo(Card o) {
int rankCom = rank.compareTo(o.rank);
return rankCom != 0 ? rankCom : suit.compareTo(o.suit);
}
}
我刚刚被介绍给类似的接口,但我不确定我的实现是正确的。 当我想使用collections.sort(cards_saver)整理卡片时会出现问题。 cards_saver是我存储卡的地方。 所有这些都很好。 collections.shuffle(cards_saver)也可以正常工作。 我执行collections.sort时遇到的问题是:
Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (List<Card>). The inferred type Card is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>
我本来会放所有我拥有的额外代码...只是这太长了。 如果我对问题的解释不够充分,请发表评论-我将尽力解释。
提前致谢
我的第一个问题是如何更改卡片等级的顺序。 在从类Card继承的每个单独的类(纸牌游戏)中,因为不同的纸牌游戏对不同的纸牌具有不同的重要性级别。
您有两种方法:
Card
,因此您可以覆盖compareTo
以使其表现相应。 Comparator
界面,该界面可方便地根据上下文重新定义对象的比较规则。 至于你得到的那个错误,那没有任何意义。 问题可能出在其他地方。
我认为对于语法错误,您必须将Card声明为(是的,我同意这看起来很奇怪)
public class Card implements Comparable<? extends Card>
然后可以在子类中重写。 但是,我发现这常常令人困惑。 另外,从设计角度来看,Bridge,Hearts和Poker中的纸牌都是相同的。 可以说,没有BridgeCard和PokerCard子类。 有一张纸牌,但有一个不同的游戏,该游戏决定您如何比较纸牌。
为了更加清楚,并且,如果您相信我的设计观点,那么为了更好的设计,请不要使用Comparable,而应使用一堆Comparators 。 例如:
static Comparator<Card> LOWBALL_POKER_COMPARATOR = new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
// Ace is LOW is lowball poker, other cards as usual
}
};
static Comparator<Card> PINOCLE_COMPARATOR = new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
// I haven't played pinocle in so long I forget the rules...
}
};
请注意, Enums可以实现Comparator ,因此您可以在Enums中拥有所有这些Comparator。 您正在玩的CardGame的特定实例/子类会在启动时为该游戏选择正确的枚举/比较器,然后您便离开了...
您的代码对我来说很好。 我刚刚向Card添加了toString方法:
import java.util.*;
class Card implements Comparable<Card> {
static enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES
}
static enum Rank {
DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
}
public Suit suit;
public Rank rank;
public Card (Rank ranker, Suit suiter) {
rank = ranker;
suit = suiter;
}
@Override
public int compareTo (Card o) {
int rankCom = rank.compareTo(o.rank);
return rankCom != 0 ? rankCom : suit.compareTo(o.suit);
}
public String toString () {
return suit.toString () + "\t" + rank.toString ();
}
}
并且-仅出于我的方便,在Rank中添加了Rank和Suit作为内部枚举,但仅将其全部包含在一个文件中-它不应影响排序。 这是测试:
public class CardTest
{
public static void main (String args[])
{
List <Card> lc = new ArrayList <Card> ();
lc.add (new Card (Card.Rank.SIX, Card.Suit.CLUBS));
lc.add (new Card (Card.Rank.TEN, Card.Suit.CLUBS));
lc.add (new Card (Card.Rank.SIX, Card.Suit.HEARTS));
lc.add (new Card (Card.Rank.ACE, Card.Suit.HEARTS));
System.out.println (lc);
Collections.sort (lc);
System.out.println (lc);
}
}
输出:
[CLUBS SIX, CLUBS TEN, HEARTS SIX, HEARTS ACE]
[CLUBS SIX, HEARTS SIX, CLUBS TEN, HEARTS ACE]
您的代码为:
lc.add (new Card (Rank.TEN, Suit.CLUBS));
代替。
如果您对Cards的订购顺序不同,则创建新的Card类可能是最简单的事情。 排除扑克,Bridge,Rommee,Blackjack等之间的相似性可能是过度设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.