Say I have an enum which is just
public enum Blah {
A, B, C, D
}
and I would like to find the enum value of a string, for example
Solution using Guava libraries. Method getPlanet () is case insensitive, so getPlanet ("MerCUrY") will return Planet.MERCURY.
package com.universe.solarsystem.planets;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Enums;
import com.google.common.base.Optional;
//Pluto and Eris are dwarf planets, who cares!
public enum Planet {
MERCURY,
VENUS,
EARTH,
MARS,
JUPITER,
SATURN,
URANUS,
NEPTUNE;
public static Planet getPlanet(String name) {
String val = StringUtils.trimToEmpty(name).toUpperCase();
Optional <Planet> possible = Enums.getIfPresent(Planet.class, val);
if (!possible.isPresent()) {
throw new IllegalArgumentException(val + "? There is no such planet!");
}
return possible.get();
}
}
Here's a nifty utility I use:
/**
* A common method for all enums since they can't have another base class
* @param <T> Enum type
* @param c enum type. All enums must be all caps.
* @param string case insensitive
* @return corresponding enum, or null
*/
public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
if( c != null && string != null ) {
try {
return Enum.valueOf(c, string.trim().toUpperCase());
} catch(IllegalArgumentException ex) {
}
}
return null;
}
Then in my enum class I usually have this to save some typing:
public static MyEnum fromString(String name) {
return getEnumFromString(MyEnum.class, name);
}
If your enums are not all caps, just change the Enum.valueOf
line.
Too bad I can't use T.class
for Enum.valueOf
as T
is erased.
Another way of doing this by using implicit static method name()
of Enum. name will return the exact string used to create that enum which can be used to check against provided string:
public enum Blah {
A, B, C, D;
public static Blah getEnum(String s){
if(A.name().equals(s)){
return A;
}else if(B.name().equals(s)){
return B;
}else if(C.name().equals(s)){
return C;
}else if (D.name().equals(s)){
return D;
}
throw new IllegalArgumentException("No Enum specified for this string");
}
}
Testing:
System.out.println(Blah.getEnum("B").name());
//it will print B B
inspiration: 10 Examples of Enum in Java
To add to the previous answers, and address some of the discussions around nulls and NPE I'm using Guava Optionals to handle absent/invalid cases. This works great for URI/parameter parsing.
public enum E {
A,B,C;
public static Optional<E> fromString(String s) {
try {
return Optional.of(E.valueOf(s.toUpperCase()));
} catch (IllegalArgumentException|NullPointerException e) {
return Optional.absent();
}
}
}
For those not aware, here's some more info on avoiding null with Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
As a switch
-version has not been mentioned yet I introduce it (reusing OP's enum):
private enum Blah {
A, B, C, D;
public static Blah byName(String name) {
switch (name) {
case "A":
return A;
case "B":
return B;
case "C":
return C;
case "D":
return D;
default:
throw new IllegalArgumentException(
"No enum constant " + Blah.class.getCanonicalName() + "." + name);
}
}
}
Since this don't give any additional value to the valueOf(String name)
method, it only makes sense to define an additional method if we want have a different behavior. If we don't want to raise an IllegalArgumentException
we can change the implementation to:
private enum Blah {
A, B, C, D;
public static Blah valueOfOrDefault(String name, Blah defaultValue) {
switch (name) {
case "A":
return A;
case "B":
return B;
case "C":
return C;
case "D":
return D;
default:
if (defaultValue == null) {
throw new NullPointerException();
}
return defaultValue;
}
}
}
By providing a default value we keep the contract of Enum.valueOf(String name)
without throwing an IllegalArgumentException
in that manner that in no case null
is returned. Therefore we throw a NullPointerException
if the name is null
and in case of default
if defaultValue
is null
. That's how valueOfOrDefault
works.
This approach adopts the design of the Map
-Interface which provides a method Map.getOrDefault(Object key, V defaultValue)
as of Java 8.
public static MyEnum getFromValue(String value) {
MyEnum resp = null;
MyEnum nodes[] = values();
for(int i = 0; i < nodes.length; i++) {
if(nodes[i].value.equals(value)) {
resp = nodes[i];
break;
}
}
return resp;
}