2008-10-27 40 views
21

考虑下面的Java枚举:如何将enum的字符串结果与overridden toString()转换回枚举?

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
      return "18 - 23"; 
     } 
    }, 
    A24TO29 { 
     public String toString() {   
      return "24 - 29"; 
     } 
    }, 
    A30TO35 { 
     public String toString() {   
      return "30 - 35"; 
     } 
    }, 

} 

有没有什么办法的字符串值转换“18 - 23”到相应的枚举值即AgeRange.A18TO23?

谢谢!

回答

30

一个记录部分,做到这一点是这样的最好的和最简单的方法:

public enum AgeRange { 
    A18TO23 ("18-23"), 
    A24TO29 ("24-29"), 
    A30TO35("30-35"); 

    private String value; 

    AgeRange(String value){ 
     this.value = value; 
    } 

    public String toString(){ 
     return value; 
    } 

    public static AgeRange getByValue(String value){ 
     for (final AgeRange element : EnumSet.allOf(AgeRange.class)) { 
      if (element.toString().equals(value)) { 
       return element; 
      } 
     } 
     return null; 
    } 
} 

然后你只需要调用getByValue()方法输入String输入 在里面。

7

你总是可以创建一个从字符串到值的映射 - 这样做是静态的,所以你只需要映射一次,假设返回的字符串在一段时间内保持不变。据我所知,没有内置任何内容。

+0

这是一个更好的方法来处理这个问题。然后在枚举出现时创建该映射,并且操作速度比迭代数组快得多。 – 2008-10-27 15:36:49

+0

我也在考虑这种方法,但在此枚举中只有大约15个值。创建地图效率更高吗? – Walter 2008-10-29 02:43:59

+0

可能不是,说实话。哈希表对于大量数据非常有用,但我怀疑比较15个值(最糟糕的情况下)与获取哈希码一样快,找到合适的存储桶等。 – 2008-10-29 06:24:29

2
for (AgeRange ar: EnumSet.allOf(AgeRange)) { 
    if (ar.toString().equals(inString)) { 
     myAnswer = ar; 
     break; 
    } 
} 

或者类似的东西?刚输入,没有运行编译器。原谅(评论)错别字...

或者使用这样的逻辑来构建一次地图。避免在运行时进行迭代。好主意,乔恩。

2

该类重写“toString()” - 因此,要获得相反的操作,您需要覆盖valueOf()toString()的输出转换回Enum值。

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
       return "18 - 23"; 
     } 
     public AgeRange valueOf (Class enumClass, String name) { 
       return A18T023 
     } 
    }, 

    . 
    . 
    . 
} 

买家当心 - 未编译的和未经考验......

的机制toString()valueOf()是的API

0

你可以尝试类似下面的东西?

static AgeRange fromString(String range) { 
    for (AgeRange ageRange : values()) { 
     if (range.equals(ageRange.toString())) { 
      return ageRange; 
     } 
    } 
    return null; 
} 

或者,正如其他人则建议,使用高速缓存方法:

private static Map<String, AgeRange> map; 

private static synchronized void registerAgeRange(AgeRange ageRange) { 
    if (map == null) { 
     map = new HashMap<String, AgeRange>(); 
    } 
    map.put(ageRange.toString(), ageRange); 
} 

AgeRange() { 
    registerAgeRange(this); 
} 

static AgeRange fromString(String range) { 
    return map.get(range); 
} 
4

根据有效的Java(第2版)第30项,也可以是(这是速度远远超过了循环)

public enum AgeRange { 
     A18TO23("18-23"), 
     A24TO29("24-29"), 
     A30TO35("30-35"); 

     private final String value; 

     AgeRange(String value){ 
      this.value = value; 
     } 

     @Override public String toString(){ 
      return value; 
     } 

     private static final Map<String, AgeRange> stringToEnum = 
      new HashMap<String, AgeRange>(); 

     static { 
      for (AgeRange r : values()) { 
       stringToEnum.put(r.toString(), r); 
      } 
     } 

     public static AgeRange getByValue(String value){ 
      return stringToEnum.get(value); 
     } 
}