Как загрузить значение перечисления из XML-файла?

#java

#java

Вопрос:

Я новичок в Java и пытаюсь проанализировать XML-файл с объектами, также имеющими параметры перечисления. У одного из перечислений также есть значение. И при разборе я получаю сообщение об ошибке (java.lang.Исключение IllegalArgumentException: нет константы перечисления com.codecool.enums.AreaToUse.4).

перечисление

 public enum AreaToUse {
    TRAFICH(6),
    TRAFICM(5),
    HOMEH(4),
    HOMEL(3);

    private final int qualified;

    AreaToUse(int qualified) {
        this.qualified = qualified;
    }

    public int getQualified() {
        return qualified;
    }
}
  

xml

 <Lumber name="pineLong" producer="Nati" load="M" value="17.3"
 qualified="4" length="3200" width="350" thickness="22"
 species="pine"/>
  

и синтаксический анализ

 for (int i = 0; i < lumbers.getLength(); i  ) {
    current = (Element) lumbers.item(i);
    result.add(new Lumber(current.getAttribute("name"),
                      current.getAttribute("producer"),
                      Load.valueOf(current.getAttribute("load")),
                 Double.parseDouble(current.getAttribute("value")),
              AreaToUse.valueOf(current.getAttribute("qualified")),
                  Integer.parseInt(current.getAttribute("length")),
                Integer.parseInt(current.getAttribute("width")),
               Integer.parseInt(current.getAttribute("thickness")),
                current.getAttribute("species")));
}
  

мой ожидаемый результат

pineLong, Nati, M, 17.3, 4, 3200, 350, 22, сосна

фактический возврат — java.lang.Исключение IllegalArgumentException: нет константы перечисления com.codecool.enums.AreaToUse.4

Комментарии:

1. Вызывается ваше значение перечисления HOMEH , а не 4 . Итак, либо вы должны изменить свой XML ( qualified="HOMEH" ), либо вы должны написать некоторый код внутри своего перечисления, чтобы сопоставить целочисленное значение со значением перечисления.

Ответ №1:

Вы должны написать метод, который возвращает право Enum по qualified значению, потому valueOf что выполняет поиск Enum по заданному String . Вот почему вы получаете сообщение No enum constant com.codecool.enums.AreaToUse.4 . У вас нет AreaToUse вызова 4 .

Попробуйте это:

 public enum AreaToUse {
    ...
    public static AreaToUse byQualified(int qualified) {
        AreaToUse returnValue = null;
        for(AreaToUse areaToUse : values()) {
            if(areaToUse.getQualified() == qualified) {
                returnValue = areaToUse;
            }
        }
        return returnValue;
    }
}
  

Вместо этого я бы рекомендовал создать карту, которая сопоставляет определенное значение с областью перечисления:

 public enum AreaToUse {

    private static final Map<Integer, AreaToUse> MAPPING = new HashMap<>();

    static {
        for(AreaToUse areaToUse : values()) {
            MAPPING.put(areaToUse.getQualified(), areaToUse);
        }
    }
    public static AreaToUse byQualified(int qualified) {
        return MAPPING.get(qualified);
    }
}
  

Ответ №2:

У вас должен быть служебный метод, подобный valueOfInt ENUM AreaToUse тому, который преобразует ваше qualified int значение в corresponding ENUM значение.

 public static AreaToUse valueOfInt(int i) {
    return Arrays.stream(AreaToUse.values())
            .filter(e -> e.getQualified() == i)
            .findFirst()
            .orElse(null);
}
  

И использовать его как:

 AreaToUse.valueOfInt(current.getAttribute("qualified"))
  

Если ваш current.getAttribute("qualified") возвращает строку, то проанализируйте ее до целого числа.

 AreaToUse.valueOfInt(Integer.parseInt(current.getAttribute("qualified")))