Alternative to if...else for keyword based actions

C

c0balt279

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?
 
S

Stefan Ram

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
 
M

Mark Space

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 );
}
 
C

c0balt279

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--;
}
 
M

Mark Space

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.");
}
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top