比较实现Comparable的对象更优雅的方式

时间:2017-10-12 14:21:37

标签: java comparable readability

我有以下对象(假设类Rank实现Comparable):

Rank rankA;
Rank rankB;

我会像这样比较它们:

if(rankA.compareTo(rankB) < 0) // rankA < rankB
    doSomething();

if(rankA.compareTo(rankB) == 0) // rankA == rankB
    doSomething();

if(rankA.compareTo(rankB) > 0) // rankA > rankB
    doSomething();

我发现上面的if语句难以阅读,即使添加了注释。是否有更优雅,更易读的解决方案?我知道我可以为此实现一个方法,但我正在寻找一个最好已经实现的解决方案,所以我不必创建一个util-method。

3 个答案:

答案 0 :(得分:2)

嗯,许多编程语言(不仅仅是Java)中的常规方法是比较函数返回一个数字,如果第一个数字在第二个数字之前,则为负数,如果两者都应被视为等级,则为零如果第一个出现在第二个之后,则为正。

如果你愿意,你可以做的是添加你自己的方法,例如:

boolean isBefore(Rank rank) {
  return this.compareTo(rank) < 0;
}

boolean isSame(Rank rank) {
  return this.compareTo(rank) == 0;
}

boolean isAfter(Rank rank) {
  return this.compareTo(rank) > 0;
}

您甚至可以使用默认方法创建自己的通用界面:

public interface EasyComparable<C> extends Comparable<C> {

  default boolean isBefore(C that) {
    return this.compareTo(that) < 0;
  }

  default boolean isSame(C that) {
    return this.compareTo(that) == 0;
  }

  default boolean isAfter(C that) {
    return this.compareTo(that) > 0;
  }
}

然后让您的Rank实施EasyComparator代替Comparator

然后你就可以做到:

if (rankA.isBefore(rankB)) {
    doSomething();
}
else if (rankA.isSame(rankB)) {
    doSomething();
}
else if (rankA.isAfter(rankB)) {
    doSomething();
}

您也可以在其他对象上执行此操作,而不仅仅是Rank

如果你对Rank类没有控制权,你也可以扩展Comparator,并添加3个默认方法,但是它们必须采用两个参数而不是一个。< / p>

答案 1 :(得分:0)

也许不是你想要的答案,但你可以使用 Kotlin 。在这里,您可以编写类似于您在评论中提到的代码:

fun main(args: Array<String>) {
    val s1 = "aaaa"
    val s2 = "bbbb"
    val s3 = "cccc"
    println("s1 < s2: ${s1 < s2}")
    println("s1 == s2: ${s1 == s2}")
    println("s1 < s2: ${s1.compareTo(s2) < 0}")
    println("s1 > s2: ${s1 > s2}")
    println("s3 > s2: ${s3 > s2}")
}

s1 < s2实际上是s1.compareTo(s2) < 0

所以 Kotlin 解决了你提到的问题。

上面代码的输出:

s1 < s2: true
s1 == s2: false
s1 < s2: true
s1 > s2: false
s3 > s2: true

答案 2 :(得分:0)

你的代码很好。我会用它如下:

int result = rankA.compareTo(rankB);
if(result == 0) {
    //do sth
} else if (result <0) {
    //do sth
} else {
    //do sth
}