2012-07-13 229 views
3

我有与编码相对应的枚举。我需要检查枚举没有重复的编码值。如何避免在java中重复的枚举值?

public enum EncodingsEnum 
{ 

ISO8859_1("ISO-8859-1",0), ISO8859_2("ISO-8859-2",1), 
    ISO8859_3("ISO-8859-3",2), ISO8859_4("ISO-8859-4",3), 
    ISO8859_5("ISO-8859-5",4), ISO8859_6("ISO-8859-6",5), 
    ISO8859_7("ISO-8859-7",6), ISO8859_8("ISO-8859-8",7), 
    ISO8859_9("ISO-8859-9",8), ISO8859_11("ISO-8859-11",9), 
    ISO8859_13("ISO-8859-13",10),ISO8859_15("ISO-8859-15",11), 
    UTF_8("UTF-8",11); 

    public static final int ENCODINGS_COUNT = EncodingsEnum.values().length; 
    private final String encodingName; 
    private final int encodingNumber; 

    EncodingsEnum(final String encodingName,int encodingNumber) 
    { 
     ReferenceChecker.checkReferenceNotNull(encodingName); 

     this.encodingName = encodingName; 
     this.encodingNumber = encodingNumber; 
    } 

    public static String getEncodingNameByNumber(int number) 
    { 
     for(EncodingsEnum encoding : EncodingsEnum.values()) 
     { 
      if(encoding.encodingNumber == number) 
      { 
       return encoding.getEncodingName(); 
      } 
     } 
     throw new RuntimeException("Encoding with this number isn't supported:" + number); 

    } 

    public static int getEncodingNumberByName(final String name) 
    { 
     for(EncodingsEnum encoding : EncodingsEnum.values()) 
     { 
      if(encoding.encodingName.equals(name)) 
      { 
       return encoding.getEncodingNumber(); 
      } 
     } 
     throw new RuntimeException("Encoding with this name isn't supported:" + name); 
    } 

    public String getEncodingName() 
    { 
     return this.encodingName; 
    } 

    public int getEncodingNumber() 
    { 
     return this.encodingNumber; 
    } 
} 

有,我可以用相同的号码作为现有编码的一个编码创建一个问题,所以我需要检查的枚举包含元这个数字,并抛出exception.But我不知道该怎么办那个想法?谢谢。

+0

你是什么意思“我可以使用与现有编码相同的编号创建编码”?在编译时'EncodingsEnum.java'的内容是最终的 - 你不能在运行时创建新的'enum'常量。在添加一个新常量之前,尝试按下“Ctrl-f”。 – 2012-07-13 09:22:26

+0

你为什么不简单地把数字作为序号?这样就保证了语言的独特性。 – 2012-07-13 11:53:31

+0

,因为我知道使用序号是一种不好的做法。 – 2012-07-13 12:08:26

回答

4

这不应该在运行时检查:它太晚了。添加一个遍历枚举值的单元测试,并检查它们是否都有不同的数字。确保始终执行单元测试,并在生成新版本的应用程序/库之前检查它们是否通过。

@Test 
public void encodingNumbersMustBeUnique() { 
    Set<Integer> numbers = new HashSet<Integer>(); 
    for (EncodingsEnum e : EncodingsEnum.values()) { 
     assertFalse(numbers.contains(e.getEncodingNumber())); 
     numbers.add(e.getEncodingNumber()); 
    } 
} 
+0

“太晚了” - 而且非常浪费。为什么一遍又一遍地检查它? – duffymo 2012-07-13 09:34:25

1

在构造函数中,您可以遍历enum的encodingNumbers,并在发现重复项时引发异常。类似这样的:

public boolean isPresent(String type){ 
      ClassType[] typeArray = ClassType.values(); 
      for(ClassType cType: typeArray){ 
       if(cType.absoluteName/*this is some private field of the class*/.equalsIgnoreCase(type)){ 
        return true; 
       } 
      } 
      return false; 
     } 

在您的构造函数中分配数字和名称之前进行上述检查。如果检查返回true,则抛出异常,否则不会。

0

解决此代码。

public enum EncodingsEnum { 
    ONE(1), 
    TWO(1); 

    private int number; 

    static { 
     if (!test()) { 
     throw new RuntimeException(); 
     } 
    } 

    private EncodingsEnum(int number) { 
     this.number = number; 
    } 

    public static boolean test() { 
     final Set<Integer> numbers = new HashSet<Integer>(); 

     for (final EncodingsEnum enc : EncodingsEnum.values()) { 
     numbers.add(enc.number); 
     } 

     return numbers.size() == EncodingsEnum.values().length; 
    }