迭代地在另一个枚举的定义中使用枚举

时间:2013-03-05 12:52:24

标签: java enums

我正在尝试通过使用Enums而不是字符串数组使我的代码对其他开发人员更具可扩展性。我有:

public enum FOO {
   A, B, C, D, E
}

public enum BAR {
   Z, Y, X, W
}

FOO中,我希望能够迭代定义:

D, E, F(Z), F(Y), F(X), F(W)

因此,当我向BAR添加项目时,它会自动将其添加到FOO。我认为它必须是FOO中的一个方法,BAR几乎肯定应该是一个内部类(因此是私有的),但我不知道该怎么做。使用

for (BAR b : BAR.values()) {}

似乎至少是解决方案的一部分。 如果它有帮助,对于上下文,我正在使用Pathfinder RPG技能,并列出每项技能:

public enum SkillsEnum {
    ACROBATICS,
    APPRAISE,
    BLUFF,
    CLIMB,
    CRAFT,
    DIPLOMACY,
    DISABLE_DEVICE,
    DISGUISE,
    ESCAPE_ARTIST,
    FLY,
    HANDLE_ANIMAL,
    HEAL,
    INTIMIDATE,
    KNOWLEDGE(KnowledgeList.values().[0])
    KNOWLEDGE(KnowledgeList.values().[1]) etc
}
enum KnowledgeList {
     ARCANA,
     DUNGEONEERING,
     ENGINEERING,
     GEOGRAPHY,
     HISTORY,
     LOCAL,
     NATURE,
     NOBILITY,
     PLANES,
     RELIGION
}

3 个答案:

答案 0 :(得分:1)

关于向BAR添加项目。 Java中的Enum是预定义常量集,您应该在编译时知道它们的值。首先无法在ENUM中添加项目。希望我已正确解释你的问题。

答案 1 :(得分:1)

枚举实例是由类似C的语法public enum E { A, B, C }神奇地创建的,你不能添加更多实例,即使它们在编译时是已知的。

根据您必须附加到每个枚举实例的逻辑数量以及您拥有多少个不同的“子枚举”类别,您可以尝试以下方法之一:

带参数的单枚举类

public enum Day {
    MONDAY(false),
    TUESDAY(false),
    WEDNESDAY(false),
    THURSDAY(false),
    FRIDAY(false),
    SATURDAY(true),
    SUNDAY(true);

    private final boolean weekend;

    private Day(boolean weekend) {
        this.weekend = weekend;
    }

    public boolean isWeekend() {
        return weekend;
    }

    public void doSomething() {
        if (isWeekend()) {
            // have fun
        } else {
            // do some work
        }
    }
}

优点:这种方法允许你有一个枚举类(例如,你可以在所有实例上轻松迭代),很简单,并且没有添加样板。

缺点:如果您经常测试类别成员资格,那么您的代码将会被if s混乱;您无法在编译时强制执行变量引用特定类别的实例。

枚举实现接口

public interface Day {
    public void doSomething();
}

public enum WorkDay implements Day {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY;

    @Override
    public void doSomething() {
        // do some work
    }
}

public enum WeekEnd implements Day {
    SATURDAY,
    SUNDAY;

    @Override
    public void doSomething() {
        // have fun
    }
}

优点:您可以对单个类别的实例进行类型安全引用;您可以在方法中隔离类别特定的代码,减少对成员资格测试的需求;可以在不修改原始代码的情况下进行扩展。

缺点:需要一些样板(对于简单的情况可能太多);你没有自动生成所有实例的集合。

有关enums implementing interfaces的更多示例,请参阅此答案。

答案 2 :(得分:0)

我没有看到将值动态添加到枚举的方法。它的设计使得所有值在编译时都是已知的。

作为替代方案,请考虑自己实现枚举(使用Type safe enum设计模式)。例如," enum" B延伸自" enum" A,并继承其所有值:

public class MyEnumA {
    private MyEnumA() {         
    }   
    public static MyEnumA a1 = new MyEnumA();
    public static MyEnumA a2 = new MyEnumA();
    public static MyEnumA a3 = new MyEnumA();
}

public class MyEnumB extends MyEnumA {
    private MyEnumB() {
        super();
    }   
    public static MyEnumB b1 = new MyEnumB();
    public static MyEnumB b2 = new MyEnumB();
    public static MyEnumB b3 = new MyEnumB();
}