如何避免java中重复的枚举值?

时间:2012-07-13 09:17:25

标签: java enums

我有与编码相对应的枚举。我需要检查枚举是否没有重复的编码值。

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

有一个问题,我可以使用与现有编码之一相同的编号创建编码,所以我需要检查枚举是否包含具有此编号的元素并抛出异常。但我不知道该怎么做。任何想法?谢谢。

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

在构造函数中,您可以遍历枚举的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,则不抛出异常。

答案 2 :(得分: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;
     }