Access to .values ​​() and .ordinal () methods of arbitrary enumeration?

I would like to have a class that emulates an EnumMap but stores int values ​​instead of some kind of object. Now, obviously, you can make EnumMap that maps to integers, but it's a lot of autoboxing that I would like to avoid if possible.

So I need a class like this:

public class EnumIntAttributeMap { enum Attribute { Height, Weight; } private final int[] values; public EnumIntAttributeMap() { this.values = new int[Attribute.values().length]; } public int getValue(Attribute a) { return this.values[a.ordinal()]; } public void setValue(Attribute a, int value) { this.values[a.ordinal()] = value; } } 

In addition, I would like to make a version that is common to all listings. Now, since the .values ​​() and .ordinal () methods are implicitly added by the compiler, it seems that the only way to access them will be with reflection, which will increase the performance that I try to get by avoiding auto-boxing, but, maybe there is something missing for me.

Any thoughts?

EDIT:

I think my initial question was unclear. I need a class that takes (as a general parameter) an enumeration, and then can use the same operations.

Therefore, I could use it with any enumeration without having to write a class for each type of enumeration every time. For example:

 enum Attribute { Height, Weight } enum AbilityScore {Str, Dex, Con, Int, Wis, Cha} IdealClass<Attribute> attributeVersion; IdealClass<AbilityScore> abilityScoreVersion; 

etc.

+7
source share
5 answers

This solution:

 public class EnumIntMap<E extends Enum<E>> { private final int[] values; public EnumIntMap(Class<E> cls) { this.values = new int[cls.getEnumConstants().length]; } public int getValue(E a) { return this.values[a.ordinal()]; } public void setValue(E a, int value) { this.values[a.ordinal()] = value; } } 

You will also have to initialize the map with the rename class.

 enum Attribute { Height, Weight } enum AbilityScore {Str, Dex, Con, Int, Wis, Cha} EnumIntMap<Attribute> attributeVersion = new EnumIntMap(Attribute.class); EnumIntMap<AbilityScore> abilityScoreVersion = new EnumIntMap(AbilityScore.class); 
+9
source

The key to doing this genetically is knowing a common binding for listing:

 <T extends Enum<T>> 

Your class can work for any enumeration as follows:

 public class EnumIntAttributeMap<T extends Enum<T>> { private final int[] values; private final Class<T> clazz; public EnumIntAttributeMap(Class<T> clazz) { this.clazz = clazz; this.values = new int[clazz.getEnumConstants().length]; } public int getValue(T a) { return this.values[a.ordinal()]; } public void setValue(T a, int value) { this.values[a.ordinal()] = value; } } 

Note that the constructor requires a type token, which is required due to erasing the java time type.

+2
source

All java Enum implicitly extend java.lang.Enum , so I think you're looking for:

 public class EnumIntAttributeMap<E extends java.lang.Enum<E>> { // [...] } 
+1
source

Read the following: Oracle Doc on Enums .

I think you could do something similar to the Planets example:

 public enum YourEnum{ HEIGHT (0), WIDTH (1); private final int index; YourEnum(int index) { this.index = index; } public int index() { return index; } } 
0
source

This is what I personally use and gives me a good standardization in the API

Common interface:

 public interface IValueEnum<T> { T value(); } 

Enums implement it as follows:

 public enum MyEnum implements IValueEnum<Integer> { WIDTH(1), HEIGHT(2); private final int value; MyEnum(int value) { this.value = value; } @Override public Integer value() { return value; } } 

Now you can get the final value by going to MyEnum.WIDTH.value (), etc. Since it uses generics, other listings can use Longs or Strings or whatever you have. This allows you to have a simple, simple Enum-based interface in the application. It also allows you to be completely shared on your map, etc.

EDIT: Based on a New Example

 public class IdealClass<T extends Enum> { T enumValue; public IdealClass() { } } 
0
source

All Articles