Fau*_*ult 29 java enums nested
这不是我被困住的问题,而是我正在寻找一种整洁的方式来编写我的代码.
基本上,我正在编写一个事件驱动的应用程序.用户触发事件,事件被发送到适当的对象,对象处理事件.现在我正在编写偶数处理程序方法,我希望使用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;
}
Run Code Online (Sandbox Code Playgroud)
然后,在另一个班级,我会有类似的东西:
public void handleEvent(Event evt) {
switch(Event.getAction()) {
case MOVE: doSomething(); break;
case FOO: doSomething(); break;
case BAR: doSomething(); break;
default: break;
}
}
Run Code Online (Sandbox Code Playgroud)
我会喜欢做的就是这样的事情(尽管我当然会坚持开关语句转换成自己的职能,以避免它变成开关和案例讨厌的毛球):
public void handleEvent(Event evt) {
switch(Event.getAction()) {
case MOVE: switch(Event.getAction()) {
case UP: break;
case DOWN: break;
case LEFT: break;
case RIGHT: break;
}
case FOO: break;
case BAR: break;
default: break;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我想创建嵌套枚举......就像这样:
public static enum Action {
public enum MOVE {UP, DOWN, LEFT, RIGHT}, FOO, BAR
}
Run Code Online (Sandbox Code Playgroud)
这不是我无法避免的情况,它只是......方便.所以虽然上面的内容实际上没有用,但有没有类似的方法来实现呢?如果我可以使用动作"MOVE.UP"发送事件,那将是很好的,并且该方法将首先将其识别为MOVE类型的动作,然后进一步确定它特别是在UP方向上.这只是一个简单的例子,如果我还可以制作更长的链,就像"DELETE.PAGE1.PARAGRAPH2.SENTENCE2.WORD11.LETTER3"那样.我看到它的方式,我只需要使用字符串和许多if/else语句.希望有更好的方法!(哦,如果有帮助的话,性能在我的情况下很重要)
Pat*_*ini 32
我相信在Java中,只要你的非枚举常量出现,你就可以简单地嵌套枚举.
enum Action
{
FOO,
BAR;
enum MOVE
{
UP,
DOWN,
LEFT,
RIGHT
}
}
Run Code Online (Sandbox Code Playgroud)
这为我编译并给了我你正在寻找的行为.
也许使用事件的继承层次结构?
所以你有了:
- abstract Event
-- MoveEvent(Direction)
-- FooEvent()
-- BarEvent()
Run Code Online (Sandbox Code Playgroud)
拥有以下内容可能更有意义:
- abstract Event
-- abstract MoveEvent
--- MoveUpEvent
--- MoveDownEvent
--- MoveRightEvent
--- MoveLeftEvent
-- FooEvent
-- BarEvent
Run Code Online (Sandbox Code Playgroud)
如果所有Move事件都有距离,则将其传递给MoveEvent构造函数(这会使波纹向下).
您可以像这样以任意顺序嵌套它们:
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("----------------------");
}
}
Run Code Online (Sandbox Code Playgroud)