Как построить функцию на лету в Java? - PullRequest
2 голосов
/ 29 марта 2010

Я анализирую текстовый файл, который отображается в некоторый код Java, например:

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..

Это нужно будет переоценить примерно тысячу раз, и я бы предпочел не пересматривать все это каждый раз. Есть ли способ сделать этот обход один раз, а затем иметь функцию, которая вызывается через раз?

Ответы [ 3 ]

3 голосов
/ 29 марта 2010

Вы можете сделать карту Runnables:

Map<String, Runnable> methods = new HashMap<String, Runnable>();
methods.put("rand", new Runnable() 
{
    public void run()
    {
        moveRandomly();
    }
});
...

тогда в вашем методе

public void eval(Node arg)
{
    Runnable command = methods.get(arg.data);
    command.run();
}
2 голосов
/ 29 марта 2010

Создать анонимный внутренний класс.

Что-то вроде:

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();
1 голос
/ 29 марта 2010

Если вы знаете все аргументы / команды, которые вы можете ожидать, я мог бы сделать это так:

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

Реализации команд:

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

тогда ваш eval () становится просто:

try {
  Args.eval(arg);
} catch (IllegalArgumentException e) {
  // Handle unknown arg.data
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...