开发者

Improve Java code: too many if's

I have several cases and I am just using simple if ... if else blocks.

How can I reduce the number of if statements in this code?

Perhaps I could use a lookup table, but I am not sure how to implement it in Java.

private int transition(char current, int state)
{
    if(state == 0)
    {
        if(current == 'b')
        {
            return 1;
        }
        else 
            return 0;
    }
 开发者_开发技巧   if(state == 1)
    {
        if(current == 'a')
        {
            return 2;
        }
        else 
            return 0;
    }
    if(state == 2)
    {
        if(current == 's')
        {
            return 3;
        }
        else 
            return 0;
    }
    if(state == 3)
    {
        if(current == 'e')
        {
            return 3;
        }
        if(current == 'b')
        {
            return 4;
        }
        else 
            return 0;
    }
    if(state == 4)
    {
        if(current == 'a')
        {
            return 5;
        }
        else 
            return 0;
    }
    if(state == 5)
    {
        if(current == 'l')
        {
            return 6;
        }
        else 
            return 0;
    }
    else
        return 0;
}


What you're trying to do looks very much like a finite state machine, and these are usually implemented with the help of a transition table. Once you set up the table, it's simply a matter of indexing to the position you want to get the return value. Assuming your return values are all less than 256, you can use a 2D byte array:

byte table[][] = new byte[NUM_STATES][NUM_CHARACTERS];
// Populate the non-zero entries of the table
table[0]['b'] = 1;
table[1]['a'] = 2;
// etc...

private int transition(char current, int state) {
  return table[state][current];
}


Well, you can easily utilize hash. Simple and clean.

    // declare hashtable
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("0-b", 1);
    map.put("1-a", 2);
    map.put("2-s", 3);
    ...

    // get result
    Integer result = map.get(state + "-" + current);
    // change null (nothing found) to zero
    return result == null ? 0 : result;


consider interfaces + enums:

interface State<T>
{
    public void State<T> step(T input);
}

enum MyState implements State<Character> {
    STATE0(0) { @Override public void MyState step(Character c) { return c == 'b' ? STATE1 : STATE0; }},
    STATE1(1) { @Override public void MyState step(Character c) { return c == 'a' ? STATE2 : STATE0; }},

    /* rest of states here */

    final private int value;
    MyState(int value) { this.value = value; }
    public int getValue() { return this.value; }
}

class SomeClass
{
   public MyState currentState = STATE0;

   public void step(char input)
   {
      this.currentState = this.currentState.step(input);
   }
}


i switch statement would be best here:

private int transition(char current, int state)
{
    switch(state)
    {
        case 0:
            return current == 'b' ? 1 : 0;
        case 1:
            return current == 'a' ? 2 : 0;
        case 2:
            return current == 's' ? 3 : 0;
        case 3:
            return current == 'e' ? 3 : (current == 'b' ? 4 : 0);
        case 4:
            return current == 'a' ? 5 : 0;
        case 5:
            return current == 'l' ? 6 : 0;
        default:
            return 0;
    }
}

And a note, theres only 5 if statements there checking pure intergers, this is not exactly an overhead.


Looks like you need a better abstraction for a finite state machine. Think about a class that encapsulates what you want in a better way so you can extend it by configuration rather than modifying code.


If this code is about to be expanded over the time, why not use a state machine? Each state will return the next state based on the character it receives. Maybe it's an overkill for this code, but it'll be a lot easier to maintain, expand & read.


Use switch statement for the outer if chain:

switch (state) {
  case 0: <code> ; break;
  case 1: <code> ; break;
  case 2: <code> ; break;
  <etc>
  default: return 0; break;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜