Reputation: 321
I'm parsing a text file that is being mapped to some java code like such:
public void eval(Node arg)
{
if(arg.data.equals("rand"))
{
moveRandomly();
}
else if(arg.data.equals("home"))
{
goHome();
}
else if(arg.data.equals("iffood"))
{
ifFoodHere(arg.left, arg.right);
}//snip..
This is going to need to be re-evaluated about a thousand times and I'd rather not have to traverse the whole thing every time. Is there any way to make this traversal once and then have it be a function that is called every other time?
Upvotes: 2
Views: 1999
Reputation: 9235
If you know all the arguments/commands you can expect, i might do it like this:
enum Args {
home, rand, iffood;
private Method method;
private Args () {
try {
this.method = Commands.class.getMethod(this.name(), Node.class);
} catch (final Exception e) {}
}
public void invoke (final Node args)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
this.method.invoke(null, args);
}
public static Args valueOf (final Node arg) {
return valueOf(arg.data);
}
public static void eval (final Node arg)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
valueOf(arg).invoke(arg);
}
}
Command implementations are:
class Commands {
public static void home (final Node arg) {
goHome(); // Call the implementation
// or simply make these bodies the implementations.
}
public static void iffood (final Node arg) {
ifFoodHere(arg.left, arg.right);
}
public static void rand (final Node arg) {
moveRandom();
}
//...
}
your eval() then becomes, simply:
try {
Args.eval(arg);
} catch (IllegalArgumentException e) {
// Handle unknown arg.data
}
Upvotes: 1
Reputation: 16655
You could make a Map of Runnables:
Map<String, Runnable> methods = new HashMap<String, Runnable>();
methods.put("rand", new Runnable()
{
public void run()
{
moveRandomly();
}
});
...
then in your method
public void eval(Node arg)
{
Runnable command = methods.get(arg.data);
command.run();
}
Upvotes: 3
Reputation: 43651
Create an anonymous inner class.
Something like:
public Callable<Void> eval(Node arg)
{
if(arg.data.equals("rand"))
{
return new Callable<Void>{ public Void call() { moveRandomly(); return null; } };
}
...
}
Callable<Void> f = eval(a);
f.call();
Upvotes: 2