Alternative to if...else for keyword based actions

Discussion in 'Java' started by c0balt279@gmail.com, Aug 4, 2008.

  1. Guest

    I was wondering if there is an alternative to if...else and
    switch(case) where you don't have to define the results. For example,
    if the input "println Hello World;" is sent to the program where
    println calls the method println(String str) with the parameter "Hello
    World". I could use string tokenizer to separate the parts of the
    word. Then looping through the tokens, I'd have to do a sequence of
    if..else like


    String token = "println";
    String parameter = "Hello World";
    if(token.equals("print")){
    println(parameter);
    }
    else if(token.equals("add")){
    add(parameter);
    }
    else if(token.equals("multiply")){
    multiply(parameter);
    }
    else if(token.equals("divide")){
    divide(parameter);
    }
    else if(token.equals("subtract")){
    subtract(parameter);
    }
    else if(token.equals("println")){
    println(parameter);
    }

    How can I override the condition check and directly call a method
    based on a string name of the method?? I'm trying to create a program
    that reads a notepad source file and executes a program based on it.
    Having all of these if...else checks was really getting annoying. Help?
     
    , Aug 4, 2008
    #1
    1. Advertising

  2. Stefan Ram Guest

    writes:
    >How can I [...] call a method based on a string name of the method?


    To call a method by the string, for example, »"method"« (and
    here, for example, with the argument list »( 5, 9 )«),

    CallMethod.java

    class Example
    {
    public static int method( int x, int y ){ return x + y; }

    public static double method( double x, double y )
    { return x + y; }}

    public class CallMethod
    {
    public static void main( String s[] ) { try
    {
    Class example = Class.forName( "Example" );
    Class[] parameterTypes = new Class[]{ int.class, int.class };
    java.lang.reflect.Method method = example.getMethod( "method", parameterTypes );
    Object[] arguments = new Object[]{ new Integer( 5 ), new Integer( 9 )};
    Object instance = null;
    Integer result =( Integer )method.invoke( instance, arguments );
    System.out.print( result.intValue() ); }
    catch( Exception e ){} }}

    System.out

    14

    BTW: Java 7 might get a string switch:

    http://tech.puredanger.com/java7#switch
     
    Stefan Ram, Aug 4, 2008
    #2
    1. Advertising

  3. Mark Space Guest

    wrote:
    > I was wondering if there is an alternative to if...else and
    > switch(case) where you don't have to define the results. For example,

    ....
    > String token = "println";
    > String parameter = "Hello World";


    You might consider making your tokens Enums. Define an abstract method
    in the Enum, and override it for each enum to "do something." Here's a
    longer link:

    <http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html>

    Example: I only implemented the println method, the rest are just
    stubbed out because I'm lazy. Exercise for the reader, and all that.


    package enumtokentest;

    public class Main {

    public static void main(String[] args) {
    String token = "println";
    String param = "Hello World!";
    Tokens t = Tokens.valueOf( token.toUpperCase() );
    t.eval( param );
    }

    }

    enum Tokens
    {
    ADD { public Object eval( Object ... paramList) { return 1;} },
    MULTIPLY { public Object eval( Object ... paramList) {return 1;} },
    DIVIDE { public Object eval( Object ... paramList) {return 1;} },
    SUBTRACT { public Object eval( Object ... paramList) {return 1;} },
    PRINTLN {
    @Override
    public Object eval(Object... paramList) {
    for (Object o : paramList) {
    System.out.print(o);
    }
    System.out.println("");
    return 1;
    }
    };
    abstract public Object eval( Object ... paramList );
    }
     
    Mark Space, Aug 4, 2008
    #3
  4. Guest

    Thanks Everyone!
    Ram's suggestion for directly manipulating the classes would work best
    for me in this instance since further on in the program the classes
    and methods will be constructed at runtime from external files. For
    functions that will be called often, I'll implement the map method to
    execute faster. I haven't worked extensively with enumerated data
    types, so I'll have to read up more on that to see how to use it best
    in this program.

    for(int k = 0; k <= 1; k++){
    System.out.println("ThankYou!");
    k--;
    }
     
    , Aug 4, 2008
    #4
  5. Mark Space Guest

    wrote:
    > Thanks Everyone!
    > Ram's suggestion for directly manipulating the classes would work best
    > for me in this instance since further on in the program the classes
    > and methods will be constructed at runtime from external files. For


    Yes, if you're going to make tokens dynamically, you'll need a Map or
    some close equivalent. Enums are only for finite lists who's values are
    known at compile time. That's the whole point of them being enumerations.

    I worked out a slightly cleaner example of Enums, using a constructor
    and a separate Action object for the evaluation part. The Action
    objects are function objects (I think) and using the pattern suggested
    by Bloch for function objects cleans up the code nicely.

    This is cut and paste parts, sorry if I miss something which causes the
    code not to compile:

    public class Main {

    public static void main(String[] args) {
    String token = "println";
    String param = "Hello World!";
    // Tokens t = Tokens.valueOf( token.toUpperCase() );
    // t.eval( param );
    Tokens2 t2 = Tokens2.valueOf( token.toUpperCase() );
    t2.eval( param );
    }

    }

    enum Tokens2
    {
    ADD( Dummy.EVAL ),
    DIVIDE( Dummy.EVAL ),
    MULTIPLY( Dummy.EVAL ),
    PRINTLN( PrintLn.EVAL ),
    SUBTRACT( Dummy.EVAL );

    final private Action action;

    Tokens2( Action a ){
    action = a;
    }
    public Object eval( Object ... parmList ) {
    return action.doIt(parmList);
    }
    }

    interface Action {
    Object doIt( Object ... paramList );
    }

    final class PrintLn implements Action
    {
    public static final PrintLn EVAL = new PrintLn();
    private PrintLn() {};
    @Override
    public Object doIt(Object... paramList) {
    for( Object o : paramList )
    System.out.print( o );
    System.out.println("");
    return 1;
    }
    }

    final class Dummy implements Action
    {
    public static final Dummy EVAL = new Dummy();
    private Dummy() {};
    public Object doIt(Object... paramList) {
    throw new UnsupportedOperationException("Not supported yet.");
    }
    }
     
    Mark Space, Aug 5, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    25
    Views:
    667
    MonkeeSage
    Oct 1, 2006
  2. Replies:
    6
    Views:
    457
    Peter Otten
    May 10, 2007
  3. Hamilton, William

    RE: keyword checker - keyword.kwlist

    Hamilton, William, May 10, 2007, in forum: Python
    Replies:
    4
    Views:
    355
  4. kj
    Replies:
    15
    Views:
    559
    Lawrence D'Oliveiro
    May 23, 2009
  5. vj
    Replies:
    3
    Views:
    240
Loading...

Share This Page