如何使用compareTo()

时间:2019-02-06 16:34:47

标签: java

我有一个课程,Card

public class Card implements Comparable<Card> {
    public enum rank {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
    private rank Rank;
    public enum suit {CLUBS, DIAMONDS, HEARTS, SPADES};
    private suit Suit;
}

我需要执行两项任务。首先- 使Card类具有可比性,以便可以使用compareTo将卡片按升序进行排序。 我已经在这里完成了此操作:

@Override
public int compareTo(Card other) {
    if(this.Rank != other.Rank) {
        if(this.Rank.ordinal() > other.Rank.ordinal()) {
        return 1;
        }
        else if(this.Rank.ordinal() < other.Rank.ordinal()) {
            return -1;
        }
        else {
            return 0;
        }
    }
    else {
        if(this.Suit.ordinal() > other.Suit.ordinal()) {
        return 1;
        }
        else if(this.Suit.ordinal() < other.Suit.ordinal()) {
            return -1;
        }
        else {
            return 0;
        }
    }
}

其次- 添加一个Comparator类作为Card类的嵌套类,称为CompareDescending。这应该用于将卡片按降序排列。 我已经在这里做到了,并且效果很好:

public static class CompareDescending implements Comparator<Card> {
    @Override
    public int compare(Card card, Card other) {
        if(card.Rank != other.Rank) {
            if(card.Rank.ordinal() < other.Rank.ordinal()) {
            return 1;
            }
            else if(card.Rank.ordinal() > other.Rank.ordinal()) {
                return -1;
            }
            else {
                return 0;
            }
        }
        else {
            if(card.Suit.ordinal() < other.Suit.ordinal()) {
            return 1;
            }
            else if(card.Suit.ordinal() > other.Suit.ordinal()) {
                return -1;
            }
            else {
                return 0;
            }
        }
    }
}

但是,我想知道我是否采用了错误的方式。我的嵌套Comparator类应该在其中使用compareTo()函数吗?这是更好的做法吗?

2 个答案:

答案 0 :(得分:5)

您的compareTo太复杂了。

enum为您实现了compareTo,用于以声明的顺序(即按序)对枚举值进行排序。

这意味着您的代码可以简单地是:

@Override
public int compareTo(Card other) {
    int cmp = this.Rank.compareTo(other.Rank);
    if (cmp == 0)
        cmp = this.Suit.compareTo(other.Suit);
    return cmp;
}

要以相反的顺序进行比较,您只需翻转要比较的对象,即编写a.compareTo(b)而不是b.compareTo(a),那么降级的Comparator实现将是:

public static class CompareDescending implements Comparator<Card> {
    @Override
    public int compare(Card card, Card other) {
        return other.compareTo(card); // descending
    }
}

记录(注释)比较是一个好主意,因为随意回顾代码可能很容易错过这一点。在这里,我通过简单地评论比较是“下降”来记录它。

答案 1 :(得分:0)

您的自定义比较器非常复杂。 Comparator类提供了合适的方法来简化自定义比较器。此外,enum实现自然顺序比较器。

要创建降序比较器,您不必重写现有的升序比较器。只需致电Comparator.reverseOrder()

class Card implements Comparable<Card> {

    public static final Comparator<Card> SORT_ASC = Comparator.<Card, Rank>comparing(card -> card.rank).thenComparing(card -> card.suit);
    public static final Comparator<Card> SORT_DESC = SORT_ASC.reversed();

    private Rank rank;
    private Suit suit;

    @Override
    public int compareTo(Card card) {
        return SORT_ASC.compare(this, card);
    }

    public enum Rank {}
    public enum Suit {}
}

演示

List<Card> cards = Collections.emptyList();
List<Card> asc = cards.stream().sorted(Card.SORT_ASC).collect(Collectors.toList());
List<Card> desc = cards.stream().sorted(Card.SORT_DESC).collect(Collectors.toList());