Java 枚举中的枚举

Java 枚举中的枚举,java,enums,nested,Java,Enums,Nested,这不是我被卡住的问题,而是我正在寻找一种整洁的方式来编写代码 本质上,我正在编写一个事件驱动的应用程序。用户触发事件,事件被发送到适当的对象,对象处理事件。现在我正在编写偶数处理程序方法,我希望使用switch语句来确定如何处理事件。现在,当我在处理一般结构时,事件类非常简单: public class Event { public static enum Action { MOVE, FOO, BAR } private Action action;

这不是我被卡住的问题,而是我正在寻找一种整洁的方式来编写代码

本质上,我正在编写一个事件驱动的应用程序。用户触发事件,事件被发送到适当的对象,对象处理事件。现在我正在编写偶数处理程序方法,我希望使用switch语句来确定如何处理事件。现在,当我在处理一般结构时,事件类非常简单:

public class Event {

    public static enum Action {
        MOVE, FOO, BAR
    }

    private Action action;
    private int duration;

    public Event(Action action, int duration) {
        this.action = action;
        this.duration = duration;
    }

    public Action getAction() {
        return action;
    }

    public int getDuration() {
        return duration;
    }
然后,在另一节课上,我将有如下内容:

public void handleEvent(Event evt) {    
    switch(Event.getAction()) {
        case MOVE: doSomething(); break;
        case FOO:  doSomething(); break;
        case BAR:  doSomething(); break;
        default: break; 
    }
}
我想做的是这样的事情(尽管我当然会将switch语句粘贴到它们自己的函数中,以避免它变成一个讨厌的开关和案例的毛球):

所以,我想创建嵌套枚举。。。像这样:

public static enum Action {
    public enum MOVE {UP, DOWN, LEFT, RIGHT}, FOO, BAR
}

这并不是说我无法避免这种情况,而是。。。方便。因此,尽管上述方法实际上不起作用,但是否有类似的方法来实现这一点?如果我可以发送一个带有“MOVE.UP”动作的事件,该方法将首先将其标识为类型为MOVE的动作,然后进一步标识它具体是朝上的。这只是一个简单的例子,如果我也能制作更长的链,比如“DELETE.PAGE1.PARAGRAPH2.SENTENCE2.WORD11.LETTER3”,那将是非常好的。在我看来,我只需要使用字符串和很多if/else语句。希望有更好的办法!(哦,在我的例子中,性能很重要,如果有帮助的话)

也许可以为事件使用继承层次结构

所以你有:

- abstract Event
-- MoveEvent(Direction)
-- FooEvent()
-- BarEvent()
可能更合理的做法是:

- abstract Event
-- abstract MoveEvent
--- MoveUpEvent
--- MoveDownEvent
--- MoveRightEvent
--- MoveLeftEvent
-- FooEvent
-- BarEvent

如果所有移动事件都有一个距离,那么将该距离传递到MoveEvent构造函数(它将向下波动)。

我相信在Java中,只要非枚举常量先出现,就可以简单地嵌套枚举

enum Action
{
    FOO,
    BAR;
    enum MOVE
    {
         UP,
         DOWN,
         LEFT,
         RIGHT 
    }
}

这为我编译并提供了您想要的行为。

您可以按如下任意顺序嵌套它们:

package nested;

import java.util.*;
import nested.Citrus.Orange;

interface HasChildren {
    Set<Enum<?>> children();
}

enum Citrus implements HasChildren {
    lemon, lime, orange;
    Set<Enum<?>> children;

    enum Orange implements HasChildren {
        navel, valencia, blood;
        Set<Enum<?>> children;
        enum Navel implements HasChildren {
            washinton, lateLane, caraCaraPink;
            public Set<Enum<?>> children() {
                return null;
            }
        }

        static {
            navel.children = new LinkedHashSet<Enum<?>>();
            navel.children.addAll(EnumSet.allOf(Navel.class));
        }

        enum Blood implements HasChildren {
            moro, taroco;
            public Set<Enum<?>> children() {
                return null;
            }
        }
        static {
            blood.children = new LinkedHashSet<Enum<?>>();
            blood.children.addAll(EnumSet.allOf(Blood.class));
        }
        public Set<Enum<?>> children() {
            return children != null ? Collections.unmodifiableSet(children) : null;
        }
    }
    static {
        orange.children = new LinkedHashSet<Enum<?>>();
        orange.children.addAll(EnumSet.allOf(Orange.class));
    }
    public Set<Enum<?>> children() {
        return children != null ? Collections.unmodifiableSet(children) : null;
    }
}
public class EnumTreeNested {
    static void visit(Class<?> clazz) {
        Object[] enumConstants = clazz.getEnumConstants();
        if (enumConstants[0] instanceof HasChildren)
            for (Object o : enumConstants)
                 visit((HasChildren) o, clazz.getName());
     }

    static void visit(HasChildren hasChildren, String prefix) {
        if (hasChildren instanceof Enum) {
            System.out.println(prefix + ' ' + hasChildren);
            if (hasChildren.children() != null) 
                for (Object o : hasChildren.children())
                    visit((HasChildren) o, prefix + ' ' + hasChildren);
        } else
            System.out.println("other " + hasChildren.getClass());
    }
    static <E extends Enum<E> & HasChildren> Set<E> foo() {
        return null;
    }
    public static void main(String[] args) {
        System.out.println(Citrus.Orange.Navel.washinton);
        visit(Citrus.lemon, "");
        System.out.println("----------------------");
        visit(Citrus.orange, "");
        System.out.println("----------------------");
        visit(Citrus.class);
        System.out.println("----------------------");
    }
}
包嵌套;
导入java.util.*;
进口柠檬、柑橘、柑橘;
接口有子项{
集合>儿童;
枚举子对象{
肚脐,巴伦西亚,血液;
Set>children(){
返回null;
}
}
静止的{
navel.children=newlinkedhashset>children(){
返回null;
}
}
静止的{
blood.children=newlinkedhashset>children(){
返回子项!=null?集合。不可修改集(子项):null;
}
}
静止的{
orange.children=newlinkedhashset>children(){
返回子项!=null?集合。不可修改集(子项):null;
}
}
公共类枚举{
静态无效访问(类clazz){
Object[]enumConstants=clazz.getEnumConstants();
if(枚举常量[0]实例的HasChildren)
对于(对象o:枚举常量)
访问((haschilds)o,clazz.getName());
}
静态无效访问(HasChildren HasChildren,字符串前缀){
if(枚举的hasChildren实例){
System.out.println(前缀+''+有子项);
if(hasChildren.children()!=null)
for(对象o:hasChildren.children())
访问((HasChildren)o,前缀+“”+HasChildren);
}否则
System.out.println(“其他”+haschilds.getClass());
}
静态集合foo(){
返回null;
}
公共静态void main(字符串[]args){
System.out.println(柑橘、橘子、肚脐、瓦辛顿);
访问(柑橘、柠檬“);
System.out.println(“-------------------------”);
访问(柑橘、橙“);
System.out.println(“-------------------------”);
参观(柑橘类);
System.out.println(“-------------------------”);
}
}

我根本不会用枚举来描述你的事件。枚举最适合于一组可数的、恒定的状态。上、下、左、右都很好,因为它们不太可能改变。MOVE、FOO、BAR感觉应该很容易添加。相反,我会使用多态性。(每个事件都实现一个接受游戏状态的doSomething).interest.and MOVE不是一个Action.Action.values()只有FOO和BARThough,Action.MOVE.UP是完全有效的,但你需要知道这一点。没有办法轻松地遍历所有枚举实例。我喜欢用这个答案了解枚举和Citrus
package nested;

import java.util.*;
import nested.Citrus.Orange;

interface HasChildren {
    Set<Enum<?>> children();
}

enum Citrus implements HasChildren {
    lemon, lime, orange;
    Set<Enum<?>> children;

    enum Orange implements HasChildren {
        navel, valencia, blood;
        Set<Enum<?>> children;
        enum Navel implements HasChildren {
            washinton, lateLane, caraCaraPink;
            public Set<Enum<?>> children() {
                return null;
            }
        }

        static {
            navel.children = new LinkedHashSet<Enum<?>>();
            navel.children.addAll(EnumSet.allOf(Navel.class));
        }

        enum Blood implements HasChildren {
            moro, taroco;
            public Set<Enum<?>> children() {
                return null;
            }
        }
        static {
            blood.children = new LinkedHashSet<Enum<?>>();
            blood.children.addAll(EnumSet.allOf(Blood.class));
        }
        public Set<Enum<?>> children() {
            return children != null ? Collections.unmodifiableSet(children) : null;
        }
    }
    static {
        orange.children = new LinkedHashSet<Enum<?>>();
        orange.children.addAll(EnumSet.allOf(Orange.class));
    }
    public Set<Enum<?>> children() {
        return children != null ? Collections.unmodifiableSet(children) : null;
    }
}
public class EnumTreeNested {
    static void visit(Class<?> clazz) {
        Object[] enumConstants = clazz.getEnumConstants();
        if (enumConstants[0] instanceof HasChildren)
            for (Object o : enumConstants)
                 visit((HasChildren) o, clazz.getName());
     }

    static void visit(HasChildren hasChildren, String prefix) {
        if (hasChildren instanceof Enum) {
            System.out.println(prefix + ' ' + hasChildren);
            if (hasChildren.children() != null) 
                for (Object o : hasChildren.children())
                    visit((HasChildren) o, prefix + ' ' + hasChildren);
        } else
            System.out.println("other " + hasChildren.getClass());
    }
    static <E extends Enum<E> & HasChildren> Set<E> foo() {
        return null;
    }
    public static void main(String[] args) {
        System.out.println(Citrus.Orange.Navel.washinton);
        visit(Citrus.lemon, "");
        System.out.println("----------------------");
        visit(Citrus.orange, "");
        System.out.println("----------------------");
        visit(Citrus.class);
        System.out.println("----------------------");
    }
}