访问任意枚举的.values()和.ordinal()方法?

时间:2013-04-25 07:05:57

标签: java

我想有一个模拟EnumMap的类,但是存储int值而不是某种对象。现在很明显你可以制作一个映射到整数的EnumMap,但是如果有可能的话,那就是我要避免的大量自动装箱。

所以我想要一个这样的课程:

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

除了我想在所有枚举中创建一个通用的版本。现在,由于.values()和.ordinal()方法是由编译器隐式添加的,似乎访问它们的唯一方法是使用反射,这会耗尽我试图通过避免获得的性能增益自动拳击,但也许有一些我想念的东西。

有什么想法吗?

修改

我认为我最初的问题不清楚。我想要一个带(作为通用参数)枚举的类,然后可以使用相同的操作。

因此我可以将它与任何类型的枚举一起使用,而无需每次都为每种枚举编写类。如:

enum Attribute { Height, Weight }

enum AbilityScore {Str, Dex, Con, Int, Wis, Cha}

IdealClass<Attribute> attributeVersion;

IdealClass<AbilityScore> abilityScoreVersion;

等等。

5 个答案:

答案 0 :(得分:9)

这是一个解决方案:

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

您还必须使用枚举类初始化地图。

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

答案 1 :(得分:2)

在遗传上做这件事的关键是知道枚举的通用界限:

<T extends Enum<T>>

您的课程可以用于任何枚举,如下所示:

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

请注意,构造函数需要类型标记,由于java的运行时类型擦除,这是必需的。

答案 2 :(得分:1)

所有java Enum隐式扩展java.lang.Enum,所以我认为你在寻找的是:

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

答案 3 :(得分:0)

请阅读:Oracle's Doc on Enums

我认为你可以做一些类似于行星示例的事情:

public enum YourEnum{
    HEIGHT (0),
    WIDTH  (1);

    private final int index;

    YourEnum(int index) {
        this.index = index;
    }
    public int index() { return index; }
}

答案 4 :(得分:0)

这是我个人使用的,并为我提供了很好的API标准化

通用界面:

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

枚举实现如下:

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

现在你可以通过去MyEnum.WIDTH.value()等获得最终值。由于它使用泛型,其他枚举可以使用Longs或Strings或者你有什么。它允许您在应用程序中使用一个简单的基于Enum的界面。它还允许您在地图等中完全通用。

编辑:基于新示例

public class IdealClass<T extends Enum> {

  T enumValue;

  public IdealClass() {
  }

}