При использовании, например, компаратора, выход метода compare
является int. Для меня кажется, что использование Enum
(например, Comparison
) со значениями, такими как Smaller
, Equal
и Larger
может сделать код более читаемым и менее подверженным ошибкам.
// The comparison result could support methods
return compare(o1, o2).ifEqual(compare(o3, o4))
// Tests can be more readable
if(compare(o1, o2) == Equal && compare(o3, o4).isNot(Larger)) ...
// The compiler can now spot mistakes like returning a meaningless number
Вы все равно можете поддерживать compare(o1, o2).toInt() <= 1
старого стиля compare(o1, o2).toInt() <= 1
и Comparison.from(i2 - i1)
.
Есть ли какая-то причина, за исключением того, что обратной совместимости было бы трудно решить?
Изменение типа возврата из int
в Enum
приведет к поломке всех существующих компараторов. Нет никакого реального преимущества использования Enum
вместо int
там, хотя это может сделать ваш код читаемым, если вы хотите вернуть значения Enum, вы должны сделать это самостоятельно, как показано ниже
if(o1 > o2){
return ComparisonResult.GREATER;
}else if(o1 < o2){
return ComparisonResult.SMALLER;
}else{
return ComparisonResult.EQUAL;
}
или команда JDK должна изменить все реализации compareTo
во многих классах JDK, таких как String, Integer и т.д., что представляет собой много ненужной работы только потому, что мы хотим, чтобы она была более читаемой :)
return val1 - val2
.
Как вы и другие уже указывали, основная причина, скорее всего, обратная совместимость.
Чтобы повысить читаемость и избежать тестового кода, например compare(o1, o2) < 0
, несколько лет назад я написал несколько полезных методов. Они не используют перечисления и не учитывают все недостатки, о которых вы упомянули, но, может быть, вы все равно их найдете полезными (библиотека Open Source):
Например. учитывая класс участника, например:
public class Participant {
private final String firstName;
private final String lastName;
private final String city;
public Participant(String firstName, String lastName, String city) {
this.firstName = firstName;
this.lastName = lastName;
this.city = city;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getCity() {
return city;
}
}
Затем вы можете написать такой компаратор:
public class ParticipantComparator implements Comparator<Participant> {
@Override
public int compare(Participant o1, Participant o2) {
if (Comparables.isEqual(o1.getFirstName(), o2.getFirstName())) {
if (Comparables.isEqual(o1.getLastName(), o2.getLastName())) {
if (Comparables.isEqual(o1.getCity(), o2.getCity())) {
return 0;
} else if (Comparables.isGreater(o1.getCity(), o2.getCity())) {
return 1;
} else {
return -1;
}
} else {
if (Comparables.isGreater(o1.getLastName(), o2.getLastName())) {
return 1;
} else {
return -1;
}
}
} else {
if (Comparables.isGreater(o1.getFirstName(), o2.getFirstName())) {
return 1;
} else {
return -1;
}
}
}
}
Если вам нравится, вы также можете использовать константы для возвращаемых значений и статического импорта для методов утилиты. Тогда код будет выглядеть так:
import static org.softsmithy.lib.util.Comparables.isEqual;
import static org.softsmithy.lib.util.Comparables.isGreater;
import java.util.Comparator;
public class ParticipantComparator implements Comparator<Participant> {
private static final int EQUAL = 0;
private static final int GREATER = 1;
private static final int LESS = -1;
@Override
public int compare(Participant o1, Participant o2) {
if (isEqual(o1.getFirstName(), o2.getFirstName())) {
if (isEqual(o1.getLastName(), o2.getLastName())) {
if (isEqual(o1.getCity(), o2.getCity())) {
return EQUAL;
} else if (isGreater(o1.getCity(), o2.getCity())) {
return GREATER;
} else {
return LESS;
}
} else {
if (isGreater(o1.getLastName(), o2.getLastName())) {
return GREATER;
} else {
return LESS;
}
}
} else {
if (isGreater(o1.getFirstName(), o2.getFirstName())) {
return GREATER;
} else {
return LESS;
}
}
}
}
Вы можете скачать библиотеку непосредственно из Maven Central:
<dependency>
<groupId>org.softsmithy.lib</groupId>
<artifactId>softsmithy-lib-core</artifactId>
<version>0.5</version>
</dependency>