Некоторые API-интерфейсы на основе местоположения (а не картотеки) - не знаю, было бы полезно для вашего проекта - расчеты времени в пути, данные общественного транспорта и пропускная способность (оценка Walk) для карт.
http://www.walkscore.com/professional/walk-score-apis.php
(Отказ от ответственности: я не писал их, но я работаю там как front end dev - так что дайте мне знать, если какая-либо документация неясна!: D)
Это действительно тяжелая проблема. Одна из вещей, которую вам нужно сделать, это указать java, что вы используете перечисление. Это означает, что вы расширяете класс Enum для своих дженериков. Однако этот класс не имеет функции values (). Таким образом, вы должны взять класс, для которого вы можете получить значения.
Следующий пример поможет вам исправить вашу проблему:
public <T extends Enum<T>> void enumValues(Class<T> enumType) {
for (T c : enumType.getEnumConstants()) {
System.out.println(c.name());
}
}
Ниже приведен пример класса оболочки вокруг Enum. Я немного странный bu - то, что мне нужно:
public class W2UIEnum<T extends Enum<T> & Resumable> {
public String id;
public String caption;
public W2UIEnum(ApplicationContext appContext, T t) {
this.id = t.getResume();
this.caption = I18N.singleInstance.getI18nString(t.name(), "enum_"
+ t.getClass().getSimpleName().substring(0, 1).toLowerCase()
+ t.getClass().getSimpleName().substring(1,
t.getClass().getSimpleName().length()), appContext
.getLocale());
}
public static <T extends Enum<T> & Resumable> List<W2UIEnum<T>> values(
ApplicationContext appContext, Class<T> enumType) {
List<W2UIEnum<T>> statusList = new ArrayList<W2UIEnum<T>>();
for (T status : enumType.getEnumConstants()) {
statusList.add(new W2UIEnum(appContext, status));
}
return statusList;
}
}
Если вы объявите Filter как
public class Filter<T extends Iterable>
, тогда
import java.util.Iterator;
public enum TimePeriod implements Iterable {
ALL("All"),
FUTURE("Future"),
NEXT7DAYS("Next 7 Days"),
NEXT14DAYS("Next 14 Days"),
NEXT30DAYS("Next 30 Days"),
PAST("Past"),
LAST7DAYS("Last 7 Days"),
LAST14DAYS("Last 14 Days"),
LAST30DAYS("Last 30 Days");
private final String name;
private TimePeriod(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
public Iterator<TimePeriod> iterator() {
return new Iterator<TimePeriod>() {
private int index;
@Override
public boolean hasNext() {
return index < LAST30DAYS.ordinal();
}
@Override
public TimePeriod next() {
switch(index++) {
case 0 : return ALL;
case 1 : return FUTURE;
case 2 : return NEXT7DAYS;
case 3 : return NEXT14DAYS;
case 4 : return NEXT30DAYS;
case 5 : return PAST;
case 6 : return LAST7DAYS;
case 7 : return LAST14DAYS;
case 8 : return LAST30DAYS;
default: throw new IllegalStateException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
И использование довольно просто:
public class Filter<T> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
this.selectedOption = selectedOption;
Iterator<TimePeriod> it = selectedOption.iterator();
while(it.hasNext()) {
availableOptions.add(it.next());
}
}
}
Использование небезопасного нажатия:
class Filter<T extends Enum<T>> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
Class<T> clazz = (Class<T>) selectedOption.getClass();
for (T option : clazz.getEnumConstants()) {
availableOptions.add(option);
}
}
}
getClass
не будет работать, если константа enum является анонимным подклассом (пример ). getDeclaringClass
следует использовать вместо этого.
– Radiodef
11 September 2017 в 17:20
Другой вариант - использовать EnumSet:
class PrintEnumConsants {
static <E extends Enum <E>> void foo(Class<E> elemType) {
for (E e : java.util.EnumSet.allOf(elemType)) {
System.out.println(e);
}
}
enum Color{RED,YELLOW,BLUE};
public static void main(String[] args) {
foo(Color.class);
}
}
Если вы уверены, что selectedOption
конструктора Filter(T selectedOption)
не является нулевым. Вы можете использовать отражение.
public class Filter<T> {
private List<T> availableOptions = new ArrayList<T>();
private T selectedOption;
public Filter(T selectedOption) {
this.selectedOption = selectedOption;
for (T option : this.selectedOption.getClass().getEnumConstants()) { // INVALID CODE
availableOptions.add(option);
}
}
}
Надеюсь, это поможет.
Для полноты JDK8 дает нам относительно чистый и более сжатый способ достижения этого без необходимости использования синтетического values()
в классе Enum:
Для простого перечисления:
private enum TestEnum {
A,
B,
C
}
И тестовый клиент:
@Test
public void testAllValues() {
System.out.println(collectAllEnumValues(TestEnum.class));
}
Это будет печатать {A, B, C}
:
public static <T extends Enum<T>> String collectAllEnumValues(Class<T> clazz) {
return EnumSet.allOf(clazz).stream()
.map(Enum::name)
.collect(Collectors.joining(", " , "\"{", "}\""));
}
Код может быть тривиально адаптирован для извлечения разных элементов или для сбора по-другому.
Чтобы получить значение общего перечисления:
protected Set<String> enum2set(Class<? extends Enum<?>> e) {
Enum<?>[] enums = e.getEnumConstants();
String[] names = new String[enums.length];
for (int i = 0; i < enums.length; i++) {
names[i] = enums[i].toString();
}
return new HashSet<String>(Arrays.asList(names));
}
Обратите внимание, что в приведенном выше методе вызов метода toString ().
И затем определите перечисление с таким метод toString ().
public enum MyNameEnum {
MR("John"), MRS("Anna");
private String name;
private MyNameEnum(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
Проблема с корнем заключается в том, что вам нужно преобразовать массив в список, верно? Вы можете сделать это, используя определенный тип (TimePeriod вместо T) и следующий код.
Поэтому используйте что-то вроде этого:
List<TimePeriod> list = new ArrayList<TimePeriod>();
list.addAll(Arrays.asList(sizes));
Теперь вы можете передать список в любой метод, который хочет список.
getFriendlyName()
. Затем вам нужно будет добавить интерфейс к вашему перечислению, а затем приспособить генерические элементы выше, чтобы потребовать как перечисление И интерфейс для типаT
. Затем функция становится примерно такой:public <E extends Enum<?> & EnumWithFriendlyName> void friendlyEnumValues(Class<T> enumType)
– Thirler 24 November 2015 в 10:50