0

parent我需要根据相同枚举类型的值以及child哪些是不同的值来触发不同的方法。目前我这样做:

switch (parent)
{
  case DEPARTMENT:
  {
    switch (child)
    {
      case TERMINAL:
      {
        event1();
        break;
      }
      case OPERATOR:
      {
        event2();
        break;
      }
    }
    break;
  }
  case OPERATOR:
  {
    switch (child)
    {
      case TERMINAL:
      {
        event3();
        break;
      }
    }
    break;
  }
}

实际代码包含 5-10 个案例,每个案例执行一行或多行长代码(具有多个参数的方法)。

我尝试用 s 填充一个二维数组,Runnable但它的执行速度要慢 2 倍。

有没有另一种写法,更易读,但几乎一样快?

4

5 回答 5

1
class SwitchTable {
    private static class EventKey {
        private EnumType parent;
        private EnumType child;
        public EventKey (EnumType p, EnumType c) { parent=p; child=c; }
        public int HashCode () { ...something... }
    } 
    private HashMap<EventKey, Integer> events;
    public void setEvent (EnumType parent, EnumType child, int eventNumber) {
         ... add a map entry to events that maps new EventKey(parent,child) 
         ... to eventNumber
    }
    public int whichEvent (EnumType parent, EnumType child) {
         ... return the map entry for new EventKey(parent,child) or 0 if not found
    }
}

// do this once to set up
SwitchTable switches = new SwitchTable();
switches.setEvent (EnumType.DEPARTMENT, EnumType.TERMINAL, 1);
switches.setEvent (EnumType.DEPARTMENT, EnumType.OPERATOR, 2);
switches.setEvent (EnumType.OPERATOR, EnumType.TERMINAL, 3);

// then
switch (switches.whichEvent(parent, child)) {
    case 1:  event1();  break;
    case 2:  event2();  break;
    case 3:  event3();  break;
}

我懒得填写所有细节,但你明白了。即使父母和孩子是不同的枚举类型,这也应该有效。您可以对 SwitchTable 使用不同的实现(例如,设置一维或二维数组来保存事件值而不是 HashMap)。我没有对此进行测试,也不知道它在速度方面的比较。我希望我没有犯任何愚蠢的语法错误。

编辑:whichEvent不必返回整数。您可以将其设为一种新enum类型,其名称反映了您可能想要采取的各种操作。这应该会提高可读性。

于 2013-10-12T00:43:51.100 回答
1

从 和 的组合值计算的整数选择器parentchild更快:

public enum Stuff { DEPARTMENT, OPERATOR, TERMINAL };
Stuff parent = ...;
Stuff child  = ...;

int selector = parent.ordinal() * Stuff.values().length + child.ordinal();
switch(selector)
{
    case 0 : // parent=DEPARTMENT child=DEPARTMENT
        ...
    case 1 : // parent=DEPARTMENT child=OPERATOR
        ...
        ...
    case 3 : // parent=OPERATOR child=DEPARTMENT
        ...
    case 8:  // parent=TERMINAL child=TERMINAL
        ...
}

某些组合可能没有意义,只需省略它们并提供 adefault中的任何内容即可。您还可以在枚举中定义常量:

private static final int n = values().length; // for brevity
public static final int DEPARTMENT_DEPARTMENT = DEPARTMENT.ordinal() * n + DEPARTMENT.ordinal()
        ...

并在案例陈述中使用它们。

于 2013-10-12T00:49:54.637 回答
1

大多数情况下,存档可读性会影响性能。这是一个仅适用于 java7 的解决方案

public class SwitchArray {

    public enum Stuff {
        DEPARTMENT, OPERATOR, TERMINAL
    };

    static Stuff parent = Stuff.DEPARTMENT;
    static Stuff child = Stuff.OPERATOR;

    /**
     * @param args
     */
    public static void main(String[] args) {
        switch (SwitchArray.parent.toString() + "_" + SwitchArray.child.toString()) {
        case "DEPARTMENT_OPERATOR":
            System.out.println("hey!");
            break;
        case "DEPARTMENT_TERMINAL":
            System.out.println("ha!");
            break;
        default:
            break;
        }
    }

}
于 2013-10-12T02:21:41.843 回答
0

向您的枚举添加一个方法(我称它为 MyEnum)

public void doFireEvent(MyEnum child) { // 每个枚举都有一个开关 }

IMO 稍微干净一些,至少它将所有代码移动到 enum 类,所以你不会看到它。:-)

(稍后添加)。这样做的一个缺点是您的 MyEnum 类必须了解/访问 event1() 等方法,这可能是不可能或不合适的。

于 2013-10-12T01:29:35.970 回答
0

只需使用更好的缩进和格式化技术并将所有这些脏逻辑封装在枚举本身中,您的代码就可以变得更具可读性。真的是你的格式比任何东西都更难追踪。

public enum MyEnum {

    OPERATOR, TERMINAL;

    public static void execute(MyEnum parent, MyEnum child) {
        switch(parent) {
            case OPERATOR:
                switch(child) {
                    case OPERATOR: event1(); break;
                    case TERMINAL: event2(); break;
                }
            break;
            case TERMINAL:
                switch(child) {
                    case TERMINAL: event3(); break;
                }
            break;
        }
    }

}
于 2013-10-12T02:06:03.950 回答