繁体   English   中英

Collections.sort,Enum,可比接口问题

[英]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继承的每个单独的类(纸牌游戏)中,因为不同的纸牌游戏对不同的纸牌具有不同的重要性级别。

您有两种方法:

  1. 由于您是继承自Card ,因此您可以覆盖compareTo以使其表现相应。
  2. 您可以看一下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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM