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 のケースが含まれ、各ケースで 1 行以上の長いコード行 (複数の引数を持つメソッド) が実行されます。

2 次元配列にRunnables を入力しようとしましたが、実行速度が 2 倍遅くなりました。

これを書く別の方法はありますか?

4

5 に答える 5

1

parentとの組み合わせた値から計算された整数セレクターは、childより高速になります。

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
        ...
}

一部の組み合わせは意味がない場合があります。それらを省略し、default何も指定しないでください。列挙型で定数を定義することもできます。

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

caseステートメントでそれらを使用します。

于 2013-10-12T00:49:54.637 に答える
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 の代わりにイベント値を保持するために 1 次元または 2 次元の配列をセットアップします)。私はこれをテストしておらず、速度に関してどのように比較されるかわかりません。愚かな構文エラーを犯していないことを願っています。

編集:whichEvent整数を返す必要はありません。enum実行したいアクションの種類を反映した名前を持つ新しいタイプにすることができます。これにより、可読性が向上するはずです。

于 2013-10-12T00:43:51.100 に答える
0

列挙型にメソッドを追加します (私はそれを MyEnum と呼んでいます)

public void doFireEvent(MyEnum child) { // 列挙型ごとに 1 つのスイッチがここに }

少しきれいな 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 に答える