The most elegant way to apply a statement found as a string in java?

Potentially dumb: Assuming I have a line containing an operator, what's the best way to apply this operator?

What I mean:

if(n.getString(1).equals("<<")) {
  result = tmp1 << tmp2;
}

for each kind of operator I. Is there a better way?

+5
source share
10 answers

May do something like:

enum Operator {

 BITSHIFT { ... }, ADD { ... }, XOR { ... }, //...etc

 Operator public static which(String s) { //...return the correct one
 }

 public abstract int apply(int a, int b); //...defined explicitly for each enum

}

returning right will be really nice if switch statements go for Strings.

This solution is as follows (without Operator.if you are using static import):

 int result = Operator.which(s).apply(a,b);

but I would go with another proven and used parser.

+7
source

Not sure if you would call it elegant, but here is one way:

interface Operation {
  int apply(int a, int b);
}

Map<String, Operation> operations = new HashMap<String, Operation>() {{
  put("+", new Operation() { public int apply(int a, int b) { return a + b; }});
  put("-", new Operation() { public int apply(int a, int b) { return a - b; }});
  put("*", new Operation() { public int apply(int a, int b) { return a * b; }});
  put("<<", new Operation() { public int apply(int a, int b) { return a << b; }});
  // some more operations here
}};

if :

result = operations.get(n.getString(1)).apply(tmp1, tmp2);
+15

- - . , .

public enum Operation {


  ADD() {
    public int perform(int a, int b) {
      return a + b;
    }
  },
  SUBTRACT() {
    public int perform(int a, int b) {
      return a - b;
    }
  },
  MULTIPLY() {
    public int perform(int a, int b) {
      return a * b;
    }
  },
  DIVIDE() {
    public int perform(int a, int b) {
      return a / b;
    }
  };

  public abstract int perform(int a, int b);

}

, - :

int result = Operation.ADD(5, 6);

, :

Map<String, Operation> symbols = new Map<String, Operation>();
symbols.put("+", Operation.ADD);
symbols.put("-", Operation.SUBTRACT);
symbols.put("/", Operation.DIVIDE);
symbols.put("*", Operation.MULTIPLY);
...

, ​​:

symbols.get(n.getString(1).apply(tmp1, tmp2));

, ,

Operation operation = symbols.get("*");
if (operation != Operation.MULTIPLY) {
  System.out.println("Foobar as usual, * is not multiply!");
}

, , , Operation.java .

, , , , , . , , . , ..

, , :

4 + 5 * 2

, 5 * 2 4 + 5. - , , ( , ..).

, , , , .

+5

, , , . JavaCC ANTLR, , Java.

(, - , / ), Ragel .

+3

, .

(, Java , ):

final Map<String,Function<(X,X), Y>> OPERATORS = { 
    "<<" : (x,y)->{x << y}, 
    "+" : (x,y)->{x + y},
    [...]
};

[...]

result1 = OPERATORS.get(n.getString(1))(tmp1, tmp2);

Java, - .

, Hank Gay, "" /. - commons-jexl. ( ), .

+2

.

public enum Operator
{
    ADD("+")
    {
        public int apply(int a, int b)
        {
            return a + b;
        }
    }

    SHIFT_LEFT("<<")
    {
        public int apply(int a, int b)
        {
            return a << b;
        }
    }

    private String opString;

    private Operator(String op)
    {
        opString = op
    }

    static public Operator getOperator(String opRep)
    {
        for (Operator o:values())
        {
            if (o.opString.equals(opRep))
                return o;
        }
        throw new IllegalArgumentException("Operation [" + opRep + "] is not valid");
    }

    abstract public int apply(int a, int b);
}

result = Operator.getOperator("<<").apply(456,4);

- , , , .

+2

JSR-223, BeanShell, , .

+1

hashCode switch, "" .

, ( , )

:

String op = "+";

switch( op.hashCode() ){
    case ADD: r = a +  b;break;
    case SUB: r = a -  b;break;
    case TMS: r = a *  b;break;
    case DIV: r = a /  b;break;
    case MOD: r = a %  b;break;
    case SLF: r = a << b;break;
    case SRG: r = a >> b;break;
    case AND: r = a &  b;break;
    case OR:  r = a |  b;break;
    case XOR:  r = a ^ b;break;
    default: out.print("Eerr!!!"); break;
}

AND :

private static final int ADD = 0x2b;

:

import static java.lang.System.out;
class Evaluator {

    private static final int ADD = 0x2b;    // +
    private static final int SUB = 0x2d;    // -
    private static final int TMS = 0x2a;    // *
    private static final int DIV = 0x2f;    // /
    private static final int MOD = 0x25;    // %
    private static final int SLF = 0x780;    // <<
    private static final int SRG = 0x7c0;    // >>
    private static final int AND = 0x26;    // &
    private static final int OR  = 0x7c;    // |
    private static final int XOR  = 0x5e;    // ^

    private int r;
    private int a;
    private String op;
    private int b;

    private Evaluator( int a, String op, int b ) {
        this.a = a; this.op = op; this.b = b;
    }
    private Evaluator eval() {
        switch( op.hashCode() ){
            case ADD: r = a +  b;break;
            case SUB: r = a -  b;break;
            case TMS: r = a *  b;break;
            case DIV: r = a /  b;break;
            case MOD: r = a %  b;break;
            case SLF: r = a << b;break;
            case SRG: r = a >> b;break;
            case AND: r = a &  b;break;
            case OR:  r = a |  b;break;
            case XOR:  r = a ^ b;break;
            default: out.print("Eerr!!!"); break;
        }
        return this;
    }

    // For testing:
    public static int evaluate( int a, String op ,  int b ) {
        return new Evaluator(a, op, b).eval().r;
    }

    public static void main( String [] args ) {
        out.printf( " 1 + 2   = %d%n", evaluate( 1 ,"+" , 2 ));
        out.printf( " 1 - 2   = %d%n", evaluate( 1 ,"-" , 2 ));
        out.printf( " 1 * 2   = %d%n", evaluate( 1 ,"*" , 2 ));
        out.printf( " 1 / 2   = %d%n", evaluate( 1 ,"/" , 2 ));
        out.printf( " 1 %% 2  = %d%n", evaluate( 1 ,"%" , 2 ));
        out.printf( " 1 << 2  = %d%n", evaluate( 1 ,"<<" , 2 ));
        out.printf( " 1 >> 2  = %d%n", evaluate( 1 ,">>" , 2 ));
        out.printf( " 1 & 2   = %d%n", evaluate( 1 ,"&" , 2 ));
        out.printf( " 1 |  2  = %d%n", evaluate( 1 ,"|" , 2 ));
        out.printf( " 1 ^ 2   = %d%n", evaluate( 1 ,"^" , 2 ));
    }
}

. ( , )

, , , , , .

p.s. - :

System.out.println( "+".hashCode() );

:

public class HexHashCode {
    public static void main( String [] args ) {
        for( String s: args ) {
            System.out.printf("private final int %s = 0x%x;    // %s\n",s,s.hashCode(), s );
        }
    }
}

java HexHashCode + - "*" / "<<" ">>" "%" "<" ">" "==" "!=" "&" "|"  "^" 
+1

.

var ops = new Dictionary<string, Func<int, int, int>> {
  {"+", (a, b) => a + b},
  {"-", (a, b) => a - b},
  {"*", (a, b) => a * b},
  {"/", (a, b) => a / b}
};

:

var c = ops["+"](2, 3);
Console.WriteLine(c);

5.

+1

@Robin: Java - , ( enum Enum, , Java-)

, , register:

private static final Map<String, Operator> registered=new HashMap<String,Operator>();
private static void register(String op, Operator impl) {
   registered.put(op, impl);
}

And then call this method in the constructor; and use the map search in the getOperator () method.

0
source

All Articles