如何在Java中使用Comparator接口?

时间:2013-11-13 00:51:23

标签: java arraylist comparator

我无法弄清楚如何正确使用Comparator界面。

注意:我不想使用我在大多数代码中看到的“一行”比较器实现,这意味着:

Collections.sort(deck, new Comparator<Card>() {
  @Override
  public int compare(Card o1, Card o2) {
   return WHATEVER;
  });

同样,我不想使用它,因为我将要对许多不同的ArrayLists进行排序,每次都这样做似乎浪费空间。我希望以某种方式让它工作,让我的compareTo方法在一个地方写一次。

我尝试了很多不同的东西,但我不熟悉接口,所以我可能会遗漏一些东西。

这是我的Card类,带有比较方法。 (注意:让我节省一些时间并说我对使用Enumerations简化代码和比较不感兴趣,我只是想学习如何正确使用Comparator。我知道它看起来很糟糕但我必须使用一些已编写代码。)

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;}

}

这是我的比较方法。我应该把它放在另一个班级或什么的?我试着用它来调用它:

Collections.sort(deck, new Comparator<Card>());

但这显然是错误的。

deck是一个ArrayList:private ArrayList<Card> deck = new ArrayList<Card>();,里面装满了各种Card对象。

6 个答案:

答案 0 :(得分:4)

您将ComparableComparator混淆。它们当然是相似的,但实际上根本不同。

Comparable定义了类的自然顺序 - 默认情况下,类的实例应该如何排序。这就是你想要的。

当您想要使用与自然顺序不同的排序顺序时,

Comparator可帮助您对类的实例进行排序。这似乎不是你的目标。

所以你真正想要的是这个:

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
}

请注意,您必须实施的方法是compareTo,这与您使用Comparator实施的方法不同。

然后你只需这样排序:

Collections.sort(deck)

卡片会知道如何自我整理。

如果您需要更多指导,我们实际上在ComparableComparator上使用tutorial上提供的文件Github。如果你愿意,请查看。

答案 1 :(得分:1)

由于您似乎只有一种比较Card对象的方法,因此您不必使用比较器。让Card实现Comparable,然后按1参数方法排序:

Collections.sort(deck);

答案 2 :(得分:1)

总结:

  • 要对数组进行排序,请使用Collections.sort(deck);
  • 您的卡类需要实施Comparable
  • 比较Strings时最好使用equals
  • 最好先使用常量String,即“Hearts”.equals(this.getSuit()),这样可以防止Null指针

答案 3 :(得分:0)

您想要实现Comparable,然后您可以对数组进行排序。

答案 4 :(得分:0)

我同意Juned,使用value1.equals(value2)这会返回一个布尔值。从事物的外观来看,你只做字符串比较,这是相当直接的前进。

祝你好运。

答案 5 :(得分:-1)

我认为这就是你的意图。我不相信你可以在字符串上使用switch语句,除非你是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;
    }
}