Get enum by its inner field
You can use a static Map<Integer,TestEnum>
with a static
initializer that populates it with the TestEnum
values keyed by their number
fields.
Note that findByKey
has been made static
, and number
has also been made final
.
import java.util.*;
public enum TestEnum {
ONE(1), TWO(2), SIXTY_NINE(69);
private final int number;
TestEnum(int number) {
this.number = number;
}
private static final Map<Integer,TestEnum> map;
static {
map = new HashMap<Integer,TestEnum>();
for (TestEnum v : TestEnum.values()) {
map.put(v.number, v);
}
}
public static TestEnum findByKey(int i) {
return map.get(i);
}
public static void main(String[] args) {
System.out.println(TestEnum.findByKey(69)); // prints "SIXTY_NINE"
System.out.println(
TestEnum.values() == TestEnum.values()
); // prints "false"
}
}
You can now expect findByKey
to be a O(1)
operation.
References
- JLS 8.7 Static initializers
- JLS 8.9 Enums
Related questions
- Static initalizer in Java
- How to Initialise a static Map in Java
Note on values()
The second println
statement in the main
method is revealing: values()
returns a newly allocated array with every invokation! The original O(N)
solution could do a little better by only calling values()
once and caching the array, but that solution would still be O(N)
on average.
How to get the enum type by its attribute?
All you need to do is add a default case so the method always returns something or throws an exception:
AreaCode area(int n){
switch (n) {
case 7927: return AreaCode.area1;
case 7928: return AreaCode.area2;
case 7929: return AreaCode.area3;
default: return null;
}
}
or perhaps better
AreaCode area(int n){
switch (n) {
case 7927: return AreaCode.area1;
case 7928: return AreaCode.area2;
case 7929: return AreaCode.area3;
default: throw new IllegalArgumentException(String.valueOf(n));
}
}
Getting Enum value by another value
The ENUM types has the method values
, which you can use to extract all the enum values and compare their identifier against the one that you have passed by the method parameter, namely:
public MyEnum getEnum(String identifier){
for(MyEnum e : MyEnum.values())
if(e.identifier.equals(identifier))
return e;
return null;
}
or even better:
public static Optional<MyEnum> getEnum(String identifier){
return Arrays.stream(MyEnum.values()).filter(i -> i.identifier.equals(identifier)).findFirst();
}
This way you make it clear on the method signature that you might or not find the enum.
Can I get an enum based on the value of its field?
For reference, here is an alternative solution with a HashMap:
enum CrimeCategory {
ASBO("Anti Social Behaviour"),
BURG("Burglary"),
CRIMDAM("Criminal Damage And Arson"),
DRUGS("Drugs"),
OTHTHEFT("Other Theft"),
PUPDISOR("Public Disorder And Weapons"),
ROBBERY("Robbery"),
SHOPLIF("Shoplifting"),
VEHICLE("Vehicle Crime"),
VIOLENT("Violent Crime"),
OTHER("Other Crime");
private static final Map<String, CrimeCategory> map = new HashMap<>(values().length, 1);
static {
for (CrimeCategory c : values()) map.put(c.category, c);
}
private final String category;
private CrimeCategory(String category) {
this.category = category;
}
public static CrimeCategory of(String name) {
CrimeCategory result = map.get(name);
if (result == null) {
throw new IllegalArgumentException("Invalid category name: " + name);
}
return result;
}
}
How to fetch value of an enum present in an inner class through Reflection
You're calling BET_TYPE_NAME.AllEven.toString()
and it is implemented in the parent Enum
class to return the same value as BET_TYPE_NAME.AllEven.name()
, thus you get "AllEven"
.
To get "12"
, you either need to override the toString()
inside the BET_TYPE_NAME
enum like:
@Override
public String toString() {
return this.value;
}
Or cast the result of Field.get(null)
to the enum BET_TYPE_NAME
and call getValue()
on it:
return Integer.toString(((TwelveByTwentyFour.BET_TYPE_NAME)
Class.forName(Test.class.getCanonicalName()+"$"+gameName+"$"+"BET_TYPE_NAME")
.getDeclaredField(betType).get(null)).getValue());
BTW, the enum should never have a setter and the value
should always be final — enum constants are shared singletons.
How can I lookup a Java enum from its String value?
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.
How to get an enum value from a string value in Java
Yes, Blah.valueOf("A")
will give you Blah.A
.
Note that the name must be an exact match, including case: Blah.valueOf("a")
and Blah.valueOf("A ")
both throw an IllegalArgumentException
.
The static methods valueOf()
and values()
are created at compile time and do not appear in source code. They do appear in Javadoc, though; for example, Dialog.ModalityType
shows both methods.
Get enum.values() from class that containing it
You can do Clazz.MyEnum.values()
to access the Enum
or you can directly import MyEnum
in your other classes import com.in.Clazz.MyEnum
becuase MyEnum
is public
.
To get MyEnum
constant via reflection, but if MyEnum
is accessible then there is no need to use reflection. You can do it in following way,
Class<?> clazz = Clazz.class;//You are getting dynamically
Class<?> enumClass = clazz.getDeclaredClasses()[0];//assuming at index 0
Enum<?>[] enumConstants = (Enum<?>[]) enumClass.getEnumConstants();
System.out.println(enumConstants[0]);
OUTPUT
Hello
Inner class for each member of enum?
One think you could do instead is have your enum implement Supplier<Context>
. Now each item would have to declare a get() method to create the individual Context sub type.
enum MyEnum implements Supplier<Context>{
FOO{ @Override public Context get(){ return new FooContext(); } },
BAR{ @Override public Context get(){ return new BarContext(); } }
}
which would make your client code much simpler:
private void handleType (MyEnum type) {
handleContext(type.get());
}
How to iterate over an enum that has custom values?
Use a stream to map an array of enum values to a list of strings.
List<String> exercises = Stream.of(DaysOfExercise.values())
.map(DaysOfExercise::getExercise)
.collect(Collectors.toList());
Related Topics
Maximum Size of a Method in Java 7 and 8
Start Mail-Client with Attachment
How to Round Time to the Nearest Quarter Hour in Java
Java Byte Array Contains Negative Numbers
Managing Dll Dependencies with Maven
What Does "An Arbitrary Object of a Particular Type" Mean in Java 8
Accessing Resource Files from External Modules
Why Does Hibernate Disable Insert Batching When Using an Identity Identifier Generator
Spring - How to Use Multiple Transaction Managers in the Same Application
Why Do Constructors in Java Not Have a Return Type
Create File with Given Size in Java
How to Get the Parent Base Class Object Super.Getclass()
How Are Constructors Called During Serialization and Deserialization
Jackson Dynamic Property Names