【问题标题】:How to use the Comparator interface in Java?如何在 Java 中使用 Comparator 接口?
【发布时间】:2013-11-13 00:51:22
【问题描述】:

我不知道如何正确使用 Comparator 界面。

注意:我不想使用我在大多数代码上看到的“单行”比较器实现,意思是:

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

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

我尝试了很多不同的东西,但我是实现接口的新手,所以我可能遗漏了一些东西。

这是我的 Card 类和它的比较方法。 (注意:让我为您节省一些时间并说我对使用枚举来简化代码和比较不感兴趣,我只是想学习如何正确使用 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&lt;Card&gt; deck = new ArrayList&lt;Card&gt;(); 填充了各种 Card 对象。

【问题讨论】:

  • 使用 equals 方法进行字符串比较而不是 ==/
  • 你混淆了Comparator&lt;T&gt;Comparable&lt;T&gt;
  • 冒着指出显而易见的风险,这里没有 compareTo 方法,你有一个 compare。比较器 != 可比较
  • 虽然说你在你的问题中强调它,但它可以做类似Collections.sort(deck, deck.get(0)); 的事情。 (这仍然不是你应该做的事情。)
  • @JonKiparsky 你是对的,没有什么是偷偷摸摸的编辑解决不了的!

标签: java arraylist comparator


【解决方案1】:

您将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 上提供了文件。喜欢就去看看吧。

【讨论】:

  • 感谢您的教程,它帮助了很多人。它为我的代码的另一部分提供了新的想法,毕竟我将使用 Comparator,因为它将为我的纸牌游戏打开新的评分选项!谢谢!
  • 很高兴为您提供帮助。祝你的项目好运!看起来很有趣。
【解决方案2】:

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

Collections.sort(deck);

【讨论】:

    【解决方案3】:

    总结一下:

    • 要对数组进行排序,请使用Collections.sort(deck);
    • 你的 Card 类需要实现Comparable
    • 比较字符串时最好使用等于
    • 最好先使用常量String,即“Hearts”.equals(this.getSuit()),这样可以防止空指针

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        我同意 Juned 的观点,使用 value1.equals(value2) 这将返回一个布尔值。从外观上看,您只进行了相当直接的字符串比较。

        祝你好运。

        【讨论】:

          【解决方案6】:

          我想这就是你想要的。我不相信你可以在字符串上使用 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;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-19
            • 2021-09-18
            • 2017-07-01
            • 2020-11-22
            • 2017-05-16
            • 2011-11-17
            相关资源
            最近更新 更多