How to Get an Enum Based on the Value of Its Field

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;
}
}

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.

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.

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 name from enum value

Since your 'value' also happens to match with ordinals you could just do:

public enum RelationActiveEnum {
Invited,
Active,
Suspended;

private final int value;

private RelationActiveEnum() {
this.value = ordinal();
}
}

And getting a enum from the value:

int value = 1;
RelationActiveEnum enumInstance = RelationActiveEnum.values()[value];

I guess an static method would be a good place to put this:

public enum RelationActiveEnum {
public static RelationActiveEnum fromValue(int value)
throws IllegalArgumentException {
try {
return RelationActiveEnum.values()[value]
} catch(ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Unknown enum value :"+ value);
}
}
}

Obviously this all falls apart if your 'value' isn't the same value as the enum ordinal.

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));
}
}

set class fields based on enum value

Use a BiConsumer<Tempclass, String> taking an instance of TempClass and a String and set the appropriate field in the class.

VALUE1(Tempclass::getField1, Tempclass::setField1),
VALUE2(Tempclass::getField2, Tempclass::setField2);

private final BiConsumer<Tempclass, String> setter;

Get the setter from the enum and pass the values to the accept method of the BiConsumer.

enumInstance.getSetter().accept(tempClassInstance, "some-value");

Get int value from enum in C#

Just cast the enum, e.g.

int something = (int) Question.Role;

The above will work for the vast majority of enums you see in the wild, as the default underlying type for an enum is int.

However, as cecilphillip points out, enums can have different underlying types.
If an enum is declared as a uint, long, or ulong, it should be cast to the type of the enum; e.g. for

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

you should use

long something = (long)StarsInMilkyWay.Wolf424B;

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.



Related Topics



Leave a reply



Submit