12.4 方法compareTo

正如你在 11.7 节中看到的,创建测试两个对象是否相等的方法 equals 大有裨益。

  1. public boolean equals(Card that) {
  2. return this.rank == that.rank
  3. && this.suit == that.suit;
  4. }

另外,如果有比较两张扑克牌的方法就好了,这样就能知道哪张牌更大。可用比较运算符(<> 等)比较基本类型值,但这些运算符对对象类型不管用。

正如你在 9.6 节看到的,Java 类 String 提供了方法 compareTo。与方法 equals 一样,我们也可以为自定义类编写方法 compareTo 的定制版本。

有些类型是“完全有序的”,即可以通过比较判断出任何两个值的大小。整数和字符串都是完全有序的。

其他的类型是“无序的”,即无法以有意义的方式来规定哪个元素更大。在 Java 中,boolean 类型是无序的;如果你编写表达式 true < false,编译器将报错。

扑克牌是“部分有序的”,这意味着有些扑克牌能够比较,有些不能。例如,我们知道梅花 3 比梅花 2 大,方块 3 比梅花 3 大,但梅花 3 和方块 2 哪个更大呢?它们一个点数更大,另一个花色更大。

要想让扑克牌是可以比较的,必须指定哪个更重要:点数还是花色。如何选择没有定规,不同的游戏可能作出不同的选择。但刚买的扑克牌是有序的,开头全部是梅花,然后全部是方块,依次类推。因此,我们现在暂时假设花色更重要。

根据上述假设,可这样编写方法 compareTo

  1. public int compareTo(Card that) {
  2. if (this.suit < that.suit) {
  3. return -1;
  4. }
  5. if (this.suit > that.suit) {
  6. return 1;
  7. }
  8. if (this.rank < that.rank) {
  9. return -1;
  10. }
  11. if (this.rank > that.rank) {
  12. return 1;
  13. }
  14. return 0;
  15. }

如果 this 更大,compareTo 将返回 1;如果 that 更大,就返回-1;如果两者相等,就返回 0。先比较花色,如果花色相同,再比较点数,如果点数也相同,就返回 0。