JDK1.7 - получение константы перечисления с точками в их значениях

Я использую стороннюю библиотеку с классом enum, как показано ниже:

public enum Version { 
VERSION
String str="v2.2"; //this i get from a props file    
System.out.println("version enum: "+Version.valueOf(str));
0("v2.0"), VERSION
String str="v2.2"; //this i get from a props file    
System.out.println("version enum: "+Version.valueOf(str));
1("v2.1"), VERSION
String str="v2.2"; //this i get from a props file    
System.out.println("version enum: "+Version.valueOf(str));
2("v2.2") private final String urlElement; Version(String urlElement) { this.urlElement = urlElement; } public String getUrlElement() { return this.urlElement; } public boolean isUrlElementRequired() { return null != this.urlElement; } }

Я читаю версию из файла реквизита, который я хочу передать этому перечислению, чтобы получить соответствующую константу перечисления, например:

String str="v2.2"; //this i get from a props file    
System.out.println("version enum: "+Version.valueOf(str));

Я получаю исключение ниже:

Exception in thread "main" java.lang.IllegalArgumentException: No enum constant com.pkg.Version.v2.2

Кажется, что «v2.2» не обрабатывается как одна строка. Я попробовал несколько способов, экранируя точку в строке, но ни один из них не работает. Я использую JDK1.7. Так что кто сталкивался с этим, подскажите.


person kaluva    schedule 24.07.2015    source источник
comment
Покажите свою полную enum декларацию. Вам нужно будет добавить метод для поиска константы enum, используя ваши свойства значения.   -  person Robby Cornelissen    schedule 24.07.2015
comment
Привет, я обновил вопрос с полным классом enum.   -  person kaluva    schedule 24.07.2015


Ответы (1)


Вам нужно будет добавить метод для поиска константы enum на основе вашего свойства value. Это может выглядеть примерно так:

public enum Version {
    VERSION_2_0("v2.0"),
    VERSION_2_1("v2.1"),
    VERSION_2_2("v2.2");

    String value;

    Version(String value) {
        this.value = value;
    }

    static Version byValue(String value) {
        for (Version version : Version.values()) {
            if (version.value.equals(value)) {
                return version;
            }
        }

        return null;
    }
}

И тогда вы можете выполнить поиск следующим образом:

Version version = Version.byValue("v2.2");

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

Обновить

Если сам enum нельзя изменить, вы можете реализовать тот же механизм в другом классе, к которому у вас есть доступ. В соответствии с вашим обновленным кодом это будет выглядеть так:

static Version byUrlElement(String urlElement) {
    for (Version version : Version.values()) {
        if (version.getUrlElement().equals(urlElement)) {
            return version;
        }
    }

    return null;
}

Или, если вы хотите провести дальнейшую оптимизацию с помощью карты:

private static final Map<String, Version> VERSION_INDEX = new HashMap<>();

static {
    for (Version version : Version.values()) {
        VERSION_INDEX.put(version.getUrlElement(), version);
    }
}

И затем вы можете выполнять поиск с помощью карты:

Version version = VERSION_INDEX.get("v2.2");
person Robby Cornelissen    schedule 24.07.2015
comment
Как я уже упоминал в своем вопросе, это класс из сторонней библиотеки, который я не могу изменить. :) - person kaluva; 24.07.2015
comment
@kaluva Какие методы предоставляет перечисление? - person Robby Cornelissen; 24.07.2015
comment
При необходимости вы можете реализовать метод byValue везде, где захотите. Нет строгой необходимости реализовывать это в Version. - person BetaRide; 24.07.2015
comment
@RobbyCornelissen, спасибо за обновление. На самом деле мне нужно передать эту версию при выполнении http-вызова в моем коде. Поэтому каждый раз такая оценка кажется узким местом в производительности. Я могу рассмотреть вариант карты, как вы предложили, чтобы избежать этого падения производительности. Просто хотел знать, нет ли другого способа поддержать это в java вместо итерации по константам перечисления? - person kaluva; 24.07.2015
comment
@kaluva Поскольку имеющиеся у вас строки не соответствуют именам перечислений, лучшее, что вы можете сделать, — это вручную сопоставить константы перечисления. Существует шаблон, который может позволить построить имя перечисления из строки с помощью некоторых манипуляций со строками, но я предполагаю, что предварительно вычисленная статическая карта работает быстрее. - person Christian Semrau; 24.07.2015
comment
@RobbyCornelissen, пока я придерживаюсь твоего подхода. Но я все еще хочу услышать любые другие хорошие предложения для достижения этого без повторения перечислений. В любом случае, спасибо, ребята, за поддержку. - person kaluva; 24.07.2015
comment
@kaluva Я обновил, чтобы включить подход с картой поиска. Перечисление нужно будет повторить только один раз при загрузке класса. - person Robby Cornelissen; 24.07.2015