2011-06-02 97 views
14

嘿,所有。所以我有一组枚举和与这些枚举相对应的整数。像这样的事情,例如:使用特定于该枚举的int设置枚举?

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在上面设置的枚举是指这些天。我期望做的是查询一个数据库,它将返回一个整数,然后将枚举数设置为基于从数据库返回的整数的对象。我可以做这样的事情:

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

但对于这里面超过100枚举设置一个枚举似乎不是很实用。

那么有没有办法做到这一点?再次,我的目标是简单地插入一个int值并返回一个枚举器,而无需为此集合中的许多枚举创建新方法。也许我应该把它做成自己的班级而不是普查员,但我希望这样做。谢谢!

+0

退房的答案和意见在这里:http://stackoverflow.com/questions/3943054/how-can-i-从值转换为枚举 – Soronthar 2011-06-02 22:05:43

回答

9

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

为了使用此值,您只需将存储在数据库中的整数转换为其对应的序号,然后将其用于access the enum value。因此,对于你的例子,如果根据自己的数据库ID枚举值的顺序的实现可能是

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

是与它们在源代码中声明相同的顺序,那么你就可以非常简单,只是使用上述方法原样(除了更改类名称)。否则,您可能需要做一些更复杂的事情来将数据库值映射到序号;也许建立一个数组,如果映射是非常非线性的。

P.S.当然,如果你这样做,那么fId字段就没有用处。

+0

语法错误:它的值(),而不是值。 – Bohemian 2011-06-02 22:15:40

+0

@Bohemian:你是什么意思? – 2011-06-02 22:16:42

+0

values()是一个方法而不是字段。代码需要是:return values()[i - 1]; (不返回值[i - 1];)。注意“值”后面的括号 – Bohemian 2011-06-03 00:33:06

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

编辑 - 汤姆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; 
    } 
} 
+0

这不行!当类的静态初始化器运行时,枚举不可用 - 尝试为自己执行它。当代码运行时,Day.values()是空的 – Bohemian 2011-06-02 22:14:46

+0

是的,我猜可能会发生,奇怪的是它在我的机器上工作。编译器优化Mybe有些不可思议。然后我建议在getDay方法中初始化CACHE懒惰。 – bigoldbrute 2011-06-02 22:18:38

+0

看起来像我以前的实现实际上是可能的,发生缓存填充的静态块必须位于其他所有内容的末尾: http://stackoverflow.com/questions/536449/cannot-refer-to-the-static-enum-field -in-an-initializer – bigoldbrute 2011-06-02 22:34:03

0

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

5

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

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我正确的枚举,你可以调用

Day.getValue(i); 

即使编号是非线性的或有间隙这种方法会奏效。

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]; 
} 
+0

@rmtheis OMG ...我不敢相信我编码。谢谢。 – Bohemian 2016-09-19 05:21:12

0

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