唯一的枚举成员值

时间:2014-05-23 14:31:06

标签: java enums

我的问题:我想在两个枚举之间指定1到1的连接。基本上是:

enum MyEnum{

    ENUM_VALUE_1,
    ENUM_VALUE_2,
    ENUM_VALUE_3,

}

enum MyOtherEnum{

    OTHER_ENUM_VALUE_1(MyEnum.ENUM_VALUE_3),
    OTHER_ENUM_VALUE_2(MyEnum.ENUM_VALUE_1),
    OTHER_ENUM_VALUE_3,
    OTHER_ENUM_VALUE_4(MyEnum.ENUM_VALUE_2),

    private MyEnum pair;

    MyOtherEnum(MyEnum pair){
        this.pair=pair;
    }

}

鉴于此代码,确保MyOtherEnum的两个实例没有相同的MyEnum对的最佳方法是什么?我想出了一些解决方案,但似乎都不好。一种解决方案是在构造函数中抛出异常,但我不确定这是否可行。另一个解决方案是一种特殊的getter方法,但可以通过简单的MyOtherEnum.values()调用轻松绕过它。

5 个答案:

答案 0 :(得分:6)

听起来你不应该将它作为运行时检查来实现。只有控制代码的开发人员做了一些不好的改变,它才会失败。检测引入错误的更改是测试的目的。

编写一个简单的测试,检查一切是否正确。其他答案已经提供了一些很好的解决方案来检查重复的枚举。而不是运行应用程序以查看枚举初始化是否失败,而是运行测试(我希望您已经编写并运行测试)。

答案 1 :(得分:2)

我把“为什么”放在一边,试着回答你的问题:

MyOtherEnum中创建一个执行检查的静态块:

static{
    // This set stores all the used values
    EnumSet<MyEnum> usedValues = EnumSet.noneOf(MyEnum.class);

    for(MyOtherEnum e : values()){
        // Value already present in the set?
        if(usedValues.contains(e.pair)) throw ...; // Duplicate 
        usedValues.add(e);
    }
}

但我必须同意这些评论:你可以简单地看看你的代码,而不是写这个检查:。

答案 2 :(得分:1)

这个怎么样:

public enum MyEnum {

    ENUM_VALUE_1,
    ENUM_VALUE_2,
    ENUM_VALUE_3,

}

// All enums taken.
private static final Set<MyEnum> taken = EnumSet.noneOf(MyEnum.class);

enum MyOtherEnum {

    OTHER_ENUM_VALUE_1(MyEnum.ENUM_VALUE_3),
    OTHER_ENUM_VALUE_2(MyEnum.ENUM_VALUE_1),
    OTHER_ENUM_VALUE_3(MyEnum.ENUM_VALUE_2),
    OTHER_ENUM_VALUE_4(MyEnum.ENUM_VALUE_2);

    private MyEnum pair;

    MyOtherEnum(MyEnum pair) {
        if (taken.contains(pair)) {
            throw new IllegalArgumentException("Cannot pair the same MyEnum with two other enums! " + this);
        }
        taken.add(pair);
        this.pair = pair;
    }

}

public void test() {
    System.out.println("Hello: " + MyOtherEnum.OTHER_ENUM_VALUE_4);
}

答案 3 :(得分:0)

我有点困惑,你的问题。您考虑过使用HashSet吗?

可以使用HashSet来确保唯一值,然后只需添加HashSet中使用的值,如果它返回false,则该值已存在。

答案 4 :(得分:0)

您可以使用静态块来测试您的链接:

import java.util.HashSet;
import java.util.Set;

public class EnumTrick {
  enum MyEnum {
    ENUM_VALUE_1, ENUM_VALUE_2, ENUM_VALUE_3,
  }

  enum MyOtherEnum {

    OTHER_ENUM_VALUE_1(MyEnum.ENUM_VALUE_3), 
    OTHER_ENUM_VALUE_2(MyEnum.ENUM_VALUE_1),
    OTHER_ENUM_VALUE_3(MyEnum.ENUM_VALUE_2), 
    OTHER_ENUM_VALUE_4(MyEnum.ENUM_VALUE_2);


    private MyEnum pair;

    MyOtherEnum(MyEnum pair) {
      this.pair = pair;

    }

    static {
      Set<MyEnum> usedEnums = new HashSet<MyEnum>();
      for(MyOtherEnum moe : MyOtherEnum.values()){
        if(! usedEnums.add(moe.pair) ){
          throw new IllegalArgumentException(moe.pair + " is already used!");
        }
      }
    }
  }

  public static void main(String [] args){
    MyOtherEnum moe = MyOtherEnum.OTHER_ENUM_VALUE_1;
  }
}

会抛出异常:

Exception in thread "main" java.lang.ExceptionInInitializerError
  at EnumTrick.main(EnumTrick.java:35)
Caused by: java.lang.IllegalArgumentException: ENUM_VALUE_2 is already used!
  at EnumTrick$MyOtherEnum.<clinit>(EnumTrick.java:28)
  ... 1 more