使用特定于该枚举的int设置枚举?

时间:2011-06-02 21:56:10

标签: java enums

嘿所有人。所以我有一组枚举和一个带有与这些枚举相对应的整数的数据库。像这样的东西,例如:

public static enum Day {
    SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);

    public final int fId;

    private Day(int id) {
        this.fId = id;
    }
}

我还有一个数据库,它只引用这些天的整数,它们对应于上面枚举集中的int。我要做的是查询一个数据库,它将返回一个整数,然后根据从db返回的整数将枚举数设置为一个对象。我可以这样做:

public static Day getDay(int i) {
    switch(i) {
    case 1:
        return Day.SUNDAY;
    case 2: 
        return Day.MONDAY;
    //And so on
    }
}

但是对于一个包含100多个枚举的枚举,这似乎不太实际。

有没有办法做到这一点?我的目标是简单地插入一个int值并返回一个枚举器,而不必为这个集合中的许多枚举创建一个新方法。也许我应该把它作为自己的类而不是枚举器,但我希望这样做。谢谢!

6 个答案:

答案 0 :(得分:10)

这是一个可行的简单实现:

public static enum Day {
    SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);

    public final int fId;

    private Day(int id) {
        this.fId = id;
    }

    public static Day forInt(int id) {
        for (Day day : values()) {
            if (day.fId == id) {
                return day;
            }
        }
        throw new IllegalArgumentException("Invalid Day id: " + id);
    }
}

如果你知道你的枚举从1开始计算,你可以简单地使用它:

public static Day forInt(int id) {
    return values()[id - 1];
}

答案 1 :(得分:9)

枚举有一个内置的ID号,即“序数”,您可以将其用于此目的,只要您有一种简单的方法可以从表示数据库中给定值的数字到达序数。枚举。对于enum值,它们在源文件中声明的顺序被分配给枚举值,从0开始,因此在您的示例中,SUNDAY的序数为0,MONDAY为1,等等。

为了使用它,您只需将存储在数据库中的整数转换为其对应的序数,然后将其用于access the enum value。因此,对于您的示例,实现可能是

private static Day[] values = Day.values();
public static Day getDay(int i) {
    return values[i - 1];
}

如果根据数据库ID的枚举值的顺序与它们在源代码中声明的顺序相同,那么您几乎可以按原样使用上述方法(除了更改类名) 。否则,您可能需要做一些更复杂的事情来将数据库值映射到序数;如果映射是高度非线性的,可能会设置一个数组。

P.S。当然,如果你这样做,fId字段就没用了。

答案 2 :(得分:6)

你的枚举类应该有一个内置的查找映射作为静态变量。因此,你的枚举类应该是类似的。

public static enum Day {
    SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);

    public final int fId;

    private Day(int id) {
        this.fId = id;
    }


   private static final Map<Integer, Day > lookup
   = new HashMap<Integer, Day >();

   static {
   for (Day s : EnumSet.allOf(Day.class))
         lookup.put(s.getIntValue(), s);
   }

   public static Day getValue(int intValue) {
      return lookup.get(intValue);
   }

}

然后基于int i检索正确的枚举,您只需调用

即可
Day.getValue(i);

即使编号是非线性的或在其中存在间隙,这种方法仍然有效。

答案 3 :(得分:1)

已编辑 - 缓存已创建懒惰。

您可以创建Map<Integer,Day>运行时并在getDay实现中使用它。

public static enum Day {
    SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);

    private static Map<Integer,Day> CACHE = null;

    private static void lazyFillCache() {
        if (CACHE != null) return;

        final Map<Integer,Day> c = new HashMap<Integer,Day>();
        for (final Day d : Day.values()) {
            c.put(d.fId, d);
        }

        CACHE = c;
    }

    public static Day getDay(int i) {
        lazyFillCache();
        return CACHE.get(i);
    }

    public final int fId;

    private Day(int id) {
        this.fId = id;
    }
}

修改 - 受Tom Hawtins评论here的启发,您也可以使用此实现,它利用了Java类加载功能:

public static enum Day {
    SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);

    private static class Cache {
        private static Map<Integer,Day> CACHE = new HashMap<Integer,Day>();

        static {
            for (final Day d : Day.values()) {
                CACHE.put(d.fId, d);
            }
        }
    }

    public static Day getDay(int i) {
        return Cache.CACHE.get(i);
    }

    public final int fId;

    private Day(int id) {
        this.fId = id;
    }
}

答案 4 :(得分:0)

Day.values()将返回枚举值的(从零开始)数组。

答案 5 :(得分:0)

Day myDay = Day.values()[x] - x是int值