Я думал, что метод values () даст мне упорядоченное представление перечисления (как упомянуто здесь), но здесь это не так. Я просто получаю элементы enum в том порядке, в котором я их создала в классе enum Letter.
Точно, порядок объявления считается значимым для перечислений, поэтому мы рады, что они возвращаются именно в таком порядке. Например, когда int i
представляет значения перечисления, выполнение values()[i]
является очень простым и эффективным способом поиска экземпляра перечисления. И наоборот, метод ordinal()
возвращает индекс экземпляра enum.
Есть ли способ вывести значения перечисления в алфавитном порядке? Нужен ли мне отдельный объект компаратора или есть встроенный способ сделать это? По сути, я бы хотел, чтобы значения сортировались по алфавиту на основе текста getDescription ():
То, что вы называете значением , вообще не определено для перечислений. Здесь, в вашем контексте, вы имеете в виду результат getDescription()
.
Как вы говорите, вы могли бы создать компаратор для этих описаний . Это было бы идеально: -)
Обратите внимание, что в общем случае вам может потребоваться несколько заказов для этих экземпляров :
- декларация заказа (это официальный заказ)
- описание заказа
- другие по мере необходимости
Вы также можете немного продвинуть понятие DescriptionComparator:
По соображениям производительности вы можете хранить вычисленные описания.
Поскольку перечисления не могут наследоваться, повторное использование кода должно быть вне класса перечисления. Позвольте мне привести пример, который мы использовали бы в наших проектах:
Теперь примеры кода ...
/** Interface for enums that have a description. */
public interface Described {
/** Returns the description. */
String getDescription();
}
public enum Letter implements Described {
// .... implementation as in the original post,
// as the method is already implemented
}
public enum Other implements Described {
// .... same
}
/** Utilities for enums. */
public abstract class EnumUtils {
/** Reusable Comparator instance for Described objects. */
public static Comparator<Described> DESCRIPTION_COMPARATOR =
new Comparator<Described>() {
public int compareTo(Described a, Described b) {
return a.getDescription().compareTo(b.getDescription);
}
};
/** Return the sorted descriptions for the enum. */
public static <E extends Enum & Described> List<String>
getSortedDescriptions(Class<E> enumClass) {
List<String> descriptions = new ArrayList<String>();
for(E e : enumClass.getEnumConstants()) {
result.add(e.getDescription());
}
Collections.sort(descriptions);
return descriptions;
}
}
// caller code
List<String> letters = EnumUtils.getSortedDescriptions(Letter.class);
List<String> others = EnumUtils.getSortedDescriptions(Other.class);
Обратите внимание, что общий код в EnumUtils
работает не только для одного перечислимого класса, но работает для любого перечислимого класса в вашем проекте, который реализует интерфейс Described
.
Как уже говорилось ранее, смысл иметь код вне перечислений (где он в противном случае принадлежал бы) - это повторное использование кода. Это не страшно для двух перечислений, но у нас в проекте более тысячи перечислений, многие из которых имеют одинаковые интерфейсы ...!