Java中如何对ArrayList中的对象进行排序

5

你好,我有一个卡牌类(Card class)......在另一个类中,我创建了一个Card对象的ArrayList。如何根据卡牌的值对ArrayList进行排序?Ace是最小的卡牌值,King是最高的。

A,2,3,4,5,6,7,8,9,T,J,Q,K

public class Card {

        char rank, suit;

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

        public void setCard(char rank, char suit){
                this.rank = rank;
                this.suit = suit;
        }

        public char getRank(){
                return rank;
        }

        public char getSuit(){
                return suit;
        }

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

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


        public String toString(){
                String str = "";
                str += this.getRank();
                str += this.getSuit();
                return str;
        }

          public boolean equals(Object obj){
               Card card = (Card) obj;
               if(this.rank == card.getRank() && this.suit == card.getSuit()){
                   return true;
               }
               return false;
           }

    public boolean isValidCard(Card card){
        char s = card.getSuit();
        char r = card.getRank();
        if(s=='H' || s=='S' || s=='D' || s=='C'){
            if(r=='A' || r=='2' || r=='3' || r=='4' || r=='5' || r=='6' || r=='7' || 
                    r=='8' || r=='9' || r=='T' || r=='J' || r=='Q' || r=='K'){
                return true;
            }                   
        }
        return false;
     }

    public boolean allowedInHigherPiles(Card card, Game game, int pile){
        if(pile>=5 && game.getPile(pile).cards.size()==0){
                if(card.getRank()!='K')
                        return false;
        }
        return true;
    }

}
8个回答

10

如果您使用枚举来代替 char 表示等级和花色,代码会更加简洁。

事实上,http://jcp.org/aboutJava/communityprocess/jsr/tiger/enum.html 中有一个卡牌样例说明了如何使用 Enum。

下面是相关的代码片段:

public class Card implements Comparable, java.io.Serializable {
    public enum Rank { deuce, three, four, five, six, seven, eight, nine, ten,
                       jack, queen, king, ace }
    public enum Suit { clubs, diamonds, hearts, spades }

    private final Rank rank;
    private final Suit suit;

    private Card(Rank rank, Suit suit) {
        if (rank == null || suit == null)
            throw new NullPointerException(rank + ", " + suit);
        this.rank = rank;
        this.suit = suit;
    }

    public Rank rank() { return rank; }
    public Suit suit() { return suit; }

    public String toString() { return rank + " of " + suit; }

    public int compareTo(Object o) {
        Card c = (Card)o;
        int rankCompare = rank.compareTo(c.rank);
        return rankCompare != 0 ? rankCompare : suit.compareTo(c.suit);
    }

    private static List<Card> sortedDeck = new ArrayList<Card>(52);
    static {
        for (Iterator<Rank> i = Rank.VALUES.iterator(); i.hasNext(); ) {
            Rank rank = i.next();
            for (Iterator<Suit> j = Suit.VALUES.iterator(); j.hasNext(); )
                sortedDeck.add(new Card(rank, j.next()));
        }
    }

    // Returns a shuffled deck
    public static List<Card> newDeck() {
        List<Card> result = new ArrayList<Card>(sortedDeck);
        Collections.shuffle(result);
        return result;
    }
}

你可以把One称为Ace,把Thirteen称为King等等。 ;) - Peter Lawrey
最终标准是使用AOL-shouty-retard-case作为枚举实例名称。使Card不可变是一个好主意。 - Tom Hawtin - tackline
Java的枚举介绍页面还提供了一个卡片示例 http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html - Pool
Comparable也是一种泛型类型。因此,您的代码应该更像这样:public class Card implements Comparable<Card>, java.io.Serializable { //... public int compareTo(Card c) { int rankCompare = rank.compareTo(c.rank); return rankCompare != 0 ? rankCompare : suit.compareTo(c.suit); } } - newacct

9
一种选择是实现Comparable接口,然后覆盖compareTo方法。完成后,使用Collections.sort(myCollection)轻松对列表进行排序。
您可能更好地避免实现Comparable并创建一个Comparator对象,有一个版本的Collections.sort可以使用该比较器。
您的比较函数可以简单地检查卡的等级,并忽略花色返回结果。
您可能想阅读Java教程中关于所有这些排序业务的部分。
更新:Bjorn正确指出,当类具有自然排序顺序时应使用Comparable。我个人认为,对于纸牌来说,没有真正的“自然顺序”,因为不同的游戏在其对Ace的解释上有所不同,因此最好避免通过将Comparable作为类的一部分来提供“语义”。

1
由于一副牌有自然的排序顺序,我建议使用Comparable接口而不是单独的Comparator类。当一个对象没有自然的排序顺序时,比如鞋子类,应该使用Comparator类。不同的人以不同的方式对他们的鞋子进行排序(按颜色、尺码、价格)。 :-) - Björn
Bjorn:我同意你的观点,但是在许多游戏中(比如二十一点和扑克),A牌的角色是会改变的,所以我们在给牌加上语义时需要小心。 - Uri

4
缺失的 CompareTo 代码:
ArrayList<Card> aCardList = new ArrayList<Card>();

    Collections.sort(aCardList, new Comparator<Card>() {

        @Override
        public int compare(Card o1, Card o2) {
            if (o1.getRank() > o2.getRank())
                return -1;
            else if (o1.getRank() < o2.getRank())
                return 1;
            else
                return 0;
        }
    });

1
public class ClassName implements Comparable<Object> {

    // Variables --------------------------------------------
    private double  comparedVariable; 


    // Constructor ------------------------------------------
    public ClassName (){}


    // Functions --------------------------------------------
    //returns the fuel weight
    public double getComparedVariable() {
        return comparedVariable;
    }


    // Overrides --------------------------------------------
    @Override
    public int compareTo(Object o) {

        ClassName classObject = (ClassName) o;

        if (this.comparedVariable> classObject.getComparedVariable())
            return 1; //make -1 to sort in decreasing order
        else if (this.comparedVariable< classObject.getComparedVariable())
            return -1;//make 1 to sort in decreasing order
        else
            return 0;
    }

}

1

您可以使用java.util.Collections类来对其进行排序。特别是,两种方法可能会很方便:

 static <T extends Comparable<? super T>>
 void sort(List<T> list)
      Sorts the specified list into ascending order, according to the natural ordering of its elements.

static <T> void sort(List<T> list, Comparator<? super T> c)
      Sorts the specified list according to the order induced by the specified comparator.

对于第一种方法,你应该让你的Card类实现Comparable接口。

对于第二种方法,你应该提供一个自定义的比较器。

这样做是为了让集合框架知道如何比较你的Card对象。

因此,例如(第一种方法),你会有这段代码:

在你的Card类中

public Class Card implements Comparable{

//member and method definitions.

public int compareTo(Object o){
   //null checks && stuff missing.

   /*compares two cards based on rank.*/   
}

List<Card> cards = getAllCards();//returns an unsorted list implementation of Card objects.

java.util.Collections.sort(cards);

1

几种较短的方法

public String toString() {
   return "" + rank + suit;
}

public boolean isValidCard(){
    return "HSDC".indexOf(suit) != -1 &&
         "A23456789TJQK".indexOf(rand) != -1;
}

1

你可以实现Comparable接口,使得元素按照等级进行比较。然后Collections.sort将会自动执行你期望的操作。


-1
public class player {
     String Fname = "";
    String Lname = "";
    ArrayList<Card> cards= new ArrayList<Card> ();
    public String getFname() {
        return Fname;
    }

    public void setFname(String Fname) {
        this.Fname = Fname;
    }

    public String getLname() {
        return Lname;
    }

    public void setLastname(String Lname) {
        this.Lname = Lname;
    }

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

    public void setCards(ArrayList<Card> cards) {
        this.cards = cards;
    }

    public player(String fname,String lname) {
        this.Fname = fname;
        this.Lname = lname;
    }
    
    public void AddCard(Card card){
        cards.add(card);
    }
    
    public void showCards(){
        System.out.println(""+Fname+" "+Lname+" holds the following cards");
        for (int i=0;i<cards.size();i++)
        {
            System.out.print(cards.get(i).toString());
        }
        System.out.println();
    }
    
    public void Sortcardsbyface()
    {
        for (int i = 0; i < cards.size() - 1; i++)
        {
            int j = i;
            for (int k = i + 1; k < cards.size(); k++)
            {
                Card c = new Card();
                if (c.toInt(cards.get(k).getFace()) < c.toInt(cards.get(j).getFace()))
                {
                    j=k;
                }

            }

            Card temp = cards.get(j);
            cards.set(j,cards.get(i));
            cards.set(i,temp);

        }
        showCards();
    }
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pokegame;

/**
 *
 * @author admin
 */
public class Card {
     private String face;
    private char suit; 

    Card(char suit,String face) {
        this.suit = suit;
        this.face = face;
    }

    Card() {
        
    }

    public String getFace() {
        return face;
    }

    public void setFace(String face) {
        this.face = face;
    }

    public char getSuit() {
        return suit;
    }

    public void setSuit(char suit) {
        this.suit = suit;
    }
   
    public String toString(){
        return face+suit;  
    }
  
    
    public int toInt(String face){
        switch(face){
            case "A":
                return 1;
            case "J":
                return 11;
            case "Q":
                return 12;
            case "K":
                return 13;
            case "2":
                return 2;
            case "3":
                return 3;
            case "4":
                return 4;        
            case "5":
                return 5;        
            case "6":
                return 6;
            case "7":
                return 7;    
            case "8":
                return 8;    
            case "9":
                return 9;    
            case "10":
                return 10;    
                
                
                
                
            default:
                return 0;
        }
    }
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接