-5

I have this enum class:

public enum IconImageTag {

    None("val1"),
    USD("val2"),
    EURO("val3");
}

given a string which represent a "value" (say `"val"1)

how can I convert it to the corresponding enum?

update

I have tried this. Why is this illegal to access static member from the ctor? I get an error.

  private final String value;
    private static final Map<String, IconImageTag> stringToEnumMap = new HashMap<>();

    IconImageTag(String value) {
        this.value = value;
        stringToEnumMap.put(value, this);
    }
Elad Benda2
  • 13,852
  • 29
  • 82
  • 157
  • 2
    Check this link : http://stackoverflow.com/questions/604424/java-convert-string-to-enum – Ahmed Ziani Apr 16 '15 at 13:59
  • possible duplicate of [how can I lookup a Java enum from its string value?](http://stackoverflow.com/questions/1080904/how-can-i-lookup-a-java-enum-from-its-string-value) – blacktide Apr 16 '15 at 13:59
  • Are you sure thoses values belong to the enums or should it be in some converter somewhere else? – Jean Logeart Apr 16 '15 at 14:00
  • "I get an error" isn't helpful. My guess is that it's a NullPointerException, but you should be very specific. – Jon Skeet Apr 16 '15 at 14:06
  • but i wrote explicitly :"illegal to access static member from the ctor" – Elad Benda2 Apr 16 '15 at 14:19
  • The ctor can't access static fields due to initialization order. See http://stackoverflow.com/questions/443980/why-cant-enums-constructor-access-static-fields – Kenster Apr 16 '15 at 14:21

2 Answers2

5

Ideally, you'd build up a Map<String, IconImageTag> and add an appropriate method. For example:

public enum IconImageTag {
    NONE("val1"),
    USD("val2"),
    EURO("val3");

    private final String value;

    private final Map<String, IconImageTag> valueMap = new HashMap<>();

    static {
        for (IconImageTag tag : values()) {
            valueMap.put(tag.value, tag);
        }
    }

    private IconImageTag(String value) {
        this.value = value;
    }

    public static IconImageTag fromValue(String value) {
        return valueMap.get(value);
    }
}

(I'd probably use a different term from "value" here, to avoid confusion with valueOf() etc...)

Note the use of the static initializer block - any static variables in an enum are initialized after the enum values themselves, which means that when the enum constructor runs, valueMap will still be null.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The second question is: should this logic be in the enum? Are those ``values`` really part of the enum or could there be different sets? – Jean Logeart Apr 16 '15 at 14:03
  • they are translation of the currencies to another langauge – Elad Benda2 Apr 16 '15 at 14:04
  • @user1065869: I would put localization data in *data* files, making it easier to add new languages etc. There are definitely situations *like* this that are reasonable, but I wouldn't recommend it for localization. – Jon Skeet Apr 16 '15 at 14:04
  • So consider having: FrenchConverter that converts whatever String to this enum, ChineseConverter that converts whatever String to this enum, etc – Jean Logeart Apr 16 '15 at 14:05
  • @JeanLogeart: I wouldn't have different converters here... I wouldn't expect the *code* to change between languages. This feels like it should be a data-driven approach. – Jon Skeet Apr 16 '15 at 14:05
  • @user1065869: I've edited my answer to explain why my code isn't the same as the code you've edited into your question :) – Jon Skeet Apr 16 '15 at 14:07
  • @JonSkeet I agree for the specific case of localization. The general idea to me is just to keep the enum as simple stupid as possible and implement the logic outside of it. – Jean Logeart Apr 16 '15 at 14:07
  • @JeanLogeart: No, I wouldn't agree on that front. It often makes perfect sense to make an enum "smart" - it keeps all the related information and logic in one place. Localization is an exception to this because it's basically data rather than code (and changing that data shouldn't require editing the Java code), but I *might* still put the localization handling into the enum itself... loading the data from properties files or whatever. – Jon Skeet Apr 16 '15 at 14:08
0

You can also iterate over every enum.

public enum IconImageTag {

None("val1"),
USD("val2"),
EURO("val3");

private final String value;
private IconImageTag(String value) {
  this.value = value;
}

public String getValue() {
  return value;
}

public static IconImageTag getByValue(String value) {
  for(IconImageTag iconImageTag : values()) {
    if(iconImageTag.getValue().equals(value)) {
      return iconImageTag;
    }
  }
  return null;
}
QBrute
  • 4,405
  • 6
  • 34
  • 40