Более элегантный способ сравнения объектов, реализующих Comparable

У меня есть следующие объекты (при условии, что класс 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();

Я нахожу вышеупомянутое, если заявления трудно читать, даже с добавленными комментариями. Есть ли более элегантное, более читаемое решение? Я знаю, что мог бы реализовать метод для этого, но я ищу решение, которое предпочтительно уже реализовано, поэтому мне не нужно создавать util-метод.

3 ответа

Ну, общепринятый способ во многих языках программирования (не только в 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 метода по умолчанию, но они должны будут принимать два аргумента вместо одного.

Ваш код хорош. Я бы использовал это как ниже:

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

Возможно, не тот ответ, который вам нужен, но вместо этого вы можете использовать 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,

Итак, Котлин решил проблему, о которой вы упомянули.

Вывод кода выше:

s1 < s2: true
s1 == s2: false
s1 < s2: true
s1 > s2: false
s3 > s2: true
Другие вопросы по тегам