Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I would like to lookup an enum from its string value (or possibly any other value). I've tried the following code but it doesn't allow static in initialisers. Is there a simple way?
public enum Verbosity {
BRIEF, NORMAL, FULL;
private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();
private Verbosity() {
stringMap.put(this.toString(), this);
public static Verbosity getVerbosity(String key) {
return stringMap.get(key);
–
–
–
Use the valueOf
method which is automatically created for each Enum.
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
For arbitrary values start with:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
return null;
Only move on later to Map implementation if your profiler tells you to.
I know it's iterating over all the values, but with only 3 enum values it's hardly worth any other effort, in fact unless you have a lot of values I wouldn't bother with a Map it'll be fast enough.
–
–
–
–
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
// Reverse-lookup map for getting a day from an abbreviation
private static final Map<String, Day> lookup = new HashMap<String, Day>();
static {
for (Day d : Day.values()) {
lookup.put(d.getAbbreviation(), d);
private Day(String abbreviation) {
this.abbreviation = abbreviation;
public String getAbbreviation() {
return abbreviation;
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
–
–
–
–
–
with Java 8 you can achieve with this way:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
–
–
@Lyle's answer is rather dangerous and I have seen it not work particularly if you make the enum a static inner class. Instead I have used something like this which will load the BootstrapSingleton maps before the enums.
Edit this should not be a problem any more with modern JVMs (JVM 1.6 or greater) but I do think there are still issues with JRebel but I haven't had a chance to retest it.
Load me first:
public final class BootstrapSingleton {
// Reverse-lookup map for getting a day from an abbreviation
public static final Map<String, Day> lookup = new HashMap<String, Day>();
Now load it in the enum constructor:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
private Day(String abbreviation) {
this.abbreviation = abbreviation;
BootstrapSingleton.lookup.put(abbreviation, this);
public String getAbbreviation() {
return abbreviation;
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
If you have an inner enum you can just define the Map above the enum definition and that (in theory) should get loaded before.
–
–
–
–
–
–
In case it helps others, the option I prefer, which is not listed here, uses Guava's Maps functionality:
public enum Vebosity {
BRIEF("BRIEF"),
NORMAL("NORMAL"),
FULL("FULL");
private String value;
private Verbosity(final String value) {
this.value = value;
public String getValue() {
return this.value;
private static ImmutableMap<String, Verbosity> reverseLookup =
Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);
public static Verbosity fromString(final String id) {
return reverseLookup.getOrDefault(id, NORMAL);
With the default you can use null
, you can throw IllegalArgumentException
or your fromString
could return an Optional
, whatever behavior you prefer.
since java 8 you can initialize the map in a single line and without static block
private static Map<String, Verbosity> stringMap = Arrays.stream(values())
.collect(Collectors.toMap(Enum::toString, Function.identity()));
–
public static final EnumRole getByValue(String value){
return Arrays.stream(EnumRole.values()).filter(enumRole -> enumRole.roleName.equals(value)).findFirst().orElse(ROLE_ANONYMOUS_USER_ROLE);
public static void main(String[] args) {
System.out.println(getByValue("internal role").roleName);
Perhaps, take a look at this. Its working for me.
The purpose of this is to lookup 'RED' with '/red_color'.
Declaring a static map
and loading the enum
s into it only once would bring some performance benefits if the enum
s are many.
public class Mapper {
public enum Maps {
COLOR_RED("/red_color", "RED");
private final String code;
private final String description;
private static Map<String, String> mMap;
private Maps(String code, String description) {
this.code = code;
this.description = description;
public String getCode() {
return name();
public String getDescription() {
return description;
public String getName() {
return name();
public static String getColorName(String uri) {
if (mMap == null) {
initializeMapping();
if (mMap.containsKey(uri)) {
return mMap.get(uri);
return null;
private static void initializeMapping() {
mMap = new HashMap<String, String>();
for (Maps s : Maps.values()) {
mMap.put(s.code, s.description);
Please put in your opinons.
If you want a default value and don't want to build lookup maps, you can create a static method to handle that.
This example also handles lookups where the expected name would start with a number.
public static final Verbosity lookup(String name) {
return lookup(name, null);
public static final Verbosity lookup(String name, Verbosity dflt) {
if (StringUtils.isBlank(name)) {
return dflt;
if (name.matches("^\\d.*")) {
name = "_"+name;
try {
return Verbosity.valueOf(name);
} catch (IllegalArgumentException e) {
return dflt;
If you need it on a secondary value, you would just build the lookup map first like in some of the other answers.
public static final Verbosity getVerbosityByValue(int value)
for(Verbosity verbosity : Verbosity.values())
if(verbosity.getValue() == value)
return verbosity ;
return ACTION_NOT_VALID;
@Override
public String toString()
return ((Integer)this.getValue()).toString();
See following link for more clarification