Почему сравнения в java 8 все еще используют int вместо Enum?

1

При использовании, например, компаратора, выход метода 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).

Есть ли какая-то причина, за исключением того, что обратной совместимости было бы трудно решить?

  • 5
    Помимо других причин, обратная совместимость для чего-то вроде этого чертовски огромна.
  • 0
    @user2357112 user2357112 Да
Показать ещё 3 комментария
Теги:
enums
comparator

2 ответа

4

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

  • 0
    Хорошо, я понимаю, что на данном этапе выгоды могут не перевесить стоимость, но есть ли присущие преимущества int представление?
  • 0
    @Samuel в случае положительных чисел в результате будет записан так же просто, как return val1 - val2 .
Показать ещё 1 комментарий
2

Как вы и другие уже указывали, основная причина, скорее всего, обратная совместимость.

Чтобы повысить читаемость и избежать тестового кода, например compare(o1, o2) < 0, несколько лет назад я написал несколько полезных методов. Они не используют перечисления и не учитывают все недостатки, о которых вы упомянули, но, может быть, вы все равно их найдете полезными (библиотека Open Source):

http://www.softsmithy.org/lib/current/docs/api/softsmithy-lib-core/org/softsmithy/lib/util/Comparables.html

Например. учитывая класс участника, например:

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>
  • 0
    Я думаю, что это более читабельно, чем идея enum. Как насчет использования примера в ответе?
  • 0
    @ Weston см. простой пример в моем обновленном ответе.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню