Java - значения доступа в общем перечислении [duplicate]

Некоторые API-интерфейсы на основе местоположения (а не картотеки) - не знаю, было бы полезно для вашего проекта - расчеты времени в пути, данные общественного транспорта и пропускная способность (оценка Walk) для карт.

http://www.walkscore.com/professional/walk-score-apis.php

(Отказ от ответственности: я не писал их, но я работаю там как front end dev - так что дайте мне знать, если какая-либо документация неясна!: D)

56
задан Tauren 5 February 2010 в 23:26
поделиться

9 ответов

Это действительно тяжелая проблема. Одна из вещей, которую вам нужно сделать, это указать java, что вы используете перечисление. Это означает, что вы расширяете класс Enum для своих дженериков. Однако этот класс не имеет функции values ​​(). Таким образом, вы должны взять класс, для которого вы можете получить значения.

Следующий пример поможет вам исправить вашу проблему:

public <T extends Enum<T>> void enumValues(Class<T> enumType) {
        for (T c : enumType.getEnumConstants()) {
             System.out.println(c.name());
        }
}
90
ответ дан Thirler 27 August 2018 в 22:05
поделиться
  • 1
    Поскольку все эти ответы в основном одинаковы, я выбираю ваш, потому что он пришел первым. Это не решение дополнительного вопроса, когда я редактировал мой вопрос, но он позволил мне решить мои непосредственные потребности и двигаться дальше. Благодаря! – Tauren 7 February 2010 в 00:41
  • 2
    Не является ли c.name () именем элемента перечисления? Как насчет возврата его стоимости? Скажем, для пункта QUIZ («quizzie»), возвращающего «quizzie», а не QUIZ. – Stephane 24 November 2015 в 10:44
  • 3
    Для этого вам нужно будет иметь метод на перечислении, который возвращает значение: getFriendlyName(). Затем вам нужно будет добавить интерфейс к вашему перечислению, а затем приспособить генерические элементы выше, чтобы потребовать как перечисление И интерфейс для типа T. Затем функция становится примерно такой: public <E extends Enum<?> & EnumWithFriendlyName> void friendlyEnumValues(Class<T> enumType) – Thirler 24 November 2015 в 10:50
  • 4
    Еще одна простая проблема с Java. – Dinei 1 June 2017 в 18:29

Ниже приведен пример класса оболочки вокруг 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;
}

}

0
ответ дан Benjamin Fuentes 27 August 2018 в 22:05
поделиться

Если вы объявите 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());
        }
    }
}
0
ответ дан Boris Pavlović 27 August 2018 в 22:05
поделиться
  • 1
    Интересный подход. Я думаю, что это будет работать без необходимости иметь класс & lt; T & gt; объявлен. Тем не менее, я бы предпочел не менять все мои перечисления, поэтому я склоняюсь к другому методу. – Tauren 5 February 2010 в 23:40

Использование небезопасного нажатия:

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);
        }
    }
}
4
ответ дан Bozho 27 August 2018 в 22:05
поделиться
  • 1
    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);
    } 

}
7
ответ дан Miserable Variable 27 August 2018 в 22:05
поделиться

Если вы уверены, что 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);
        }
    }
}

Надеюсь, это поможет.

1
ответ дан NawaMan 27 August 2018 в 22:05
поделиться

Для полноты 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(", " , "\"{", "}\""));
}

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

4
ответ дан quantum 27 August 2018 в 22:05
поделиться

Чтобы получить значение общего перечисления:

  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;
  }

}
0
ответ дан Stephane 27 August 2018 в 22:05
поделиться

Проблема с корнем заключается в том, что вам нужно преобразовать массив в список, верно? Вы можете сделать это, используя определенный тип (TimePeriod вместо T) и следующий код.

Поэтому используйте что-то вроде этого:

List<TimePeriod> list = new ArrayList<TimePeriod>();
list.addAll(Arrays.asList(sizes));

Теперь вы можете передать список в любой метод, который хочет список.

0
ответ дан Steve McLeod 27 August 2018 в 22:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: