Как создать универсальный метод для возврата массива значений перечисления вместо его констант?
У меня есть перечисление с описаниями как String. Это перечисление.
public enum tabs
{
A("Actual data"),
B("Bad data"),
C("Can data"),
D("Direct data");
private String description;
tabs(String desc)
{
this.description = desc;
}
public String getDescription()
{
return this.description;
}
}
Теперь, если мне нужны данные для А, я просто сделаю
tabs.A.description
Я нахожусь в процессе создания универсального метода для возврата значений.
Мне удалось использовать приведенный ниже универсальный метод, чтобы принять тип enum в качестве аргумента. Возвращает массив перечисляемых констант. Но на самом деле я хочу, чтобы он возвращал массив значений.. т.е. {"Фактические данные", "Неверные данные", "Могут данные", "Прямые данные"}.
public static String[] getActualTabs(Class<? extends Enum<?>> e)
{
return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new);
}
Какие варианты у меня есть, чтобы достичь этого?
Ответы
Ответ 1
Вы можете передать сопоставитель Function
для отображения перечислений константы INTO String
s:
public static <T extends Enum<T>> String[] getActualTabs(Class<T> e, Function<? super T, String> mapper)
{
return Arrays.stream(e.getEnumConstants()).map(mapper).toArray(String[]::new);
}
Использование:
System.out.println(Arrays.toString(getActualTabs(tabs.class,tabs::getDescription)));
Выход:
[Actual data, Bad data, Can data, Direct data]
Ответ 2
Сначала я getDescription
из интерфейса и убедитесь, что все перечисленные в вашем проекте его реализуют:
public interface HasDescription {
String getDescription();
}
И затем, используйте это в своем родовом методе:
public static String[] getActualTabs(Class<? extends Enum<?> & HasDescription> e) {
return Arrays.stream(e.getEnumConstants())
.map(HasDescription::getDescription)
.toArray(String[]::new);
}
Ответ 3
Оба ответа довольно красивые.
Но есть и другой вариант, который может быть лучше, потому что он еще более широк:
public static <T> String[] getActualTabs(T[] values, Function<? super T, String> mapper) {
return Arrays.stream(values)
.map(mapper)
.toArray(String[]::new);
}
public static <T extends HasDescription> String[] getActualTabs(T[] values) {
return Arrays.stream(values)
.map(HasDescription::getDescription)
.toArray(String[]::new);
// or just: return getActualTabs(values, HasDescription::getDescription);
}
Эта реализация имеет то преимущество, что нам не нужно возиться с отражением.
Вместо этого вы бы назвали их так:
String[] tabs1 = getActualTabs(Tabs.values())
String[] tabs2 = getActualTabs(Tabs.values(), Tabs::getDescription)
Обратите внимание, что может быть полезно переименовать функции, например, getStringifiedValues()
или toDescriptions()
.
Отказ от ответственности: не проверено, но должно работать, ИМХО.