Более элегантный способ сравнения объектов, реализующих 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