Java Equivalent Of Function Mapping In Python
Solution 1:
Java doesn't have first-class methods, so the command pattern is your friend...
disclamer: code not tested!
publicinterfaceCommand
{
voidinvoke();
}
Map<String, Command> commands = new HashMap<String, Command>();
commands.put("function1", new Command()
{
publicvoidinvoke() { System.out.println("hello world"); }
});
commands.get("function1").invoke();
Solution 2:
There are several ways to approach this problem. Most of these were posted already:
- Commands - Keep a bunch of objects that have an execute() or invoke() method in a map; lookup the command by name, then invoke the method.
- Polymorphism - More generally than commands, you can invoke methods on any related set of objects.
- Finally there is Reflection - You can use reflection to get references to java.lang.Method objects. For a set of known classes/methods, this works fairly well and there isn't too much overhead once you load the Method objects. You could use this to, for example, allow a user to type java code into a command line, which you execute in real time.
Personally I would use the Command approach. Commands combine well with Template Methods, allowing you to enforce certain patterns on all your command objects. Example:
publicabstractclassCommand {
public final Objectexecute(Map<String, Object> args) {
// do permission checking here or transaction managementObject retval = doExecute(args);
// do logging, cleanup, caching, etc herereturn retval;
}
// subclasses override this to do the real workprotectedabstractObjectdoExecute(Map<String, Object> args);
}
I would resort to reflection only when you need to use this kind of mapping for classes whose design you don't control, and for which it's not practical to make commands. For example, you couldn't expose the Java API in a command-shell by making commands for each method.
Solution 3:
You could use a Map<String,Method> or Map<String,Callable> etc,and then use map.get("function1").invoke(...). But usually these kinds of problems are tackled more cleanly by using polymorphism instead of a lookup.
Solution 4:
Polymorphic example..
publicinterfaceAnimal {publicvoidspeak();};
publicclassDogimplementsAnimal {publicvoidspeak(){System.out.println("treat? treat? treat?");}}
publicclassCatimplementsAnimal {publicvoidspeak(){System.out.println("leave me alone");}}
publicclassHamsterimplementsAnimal {publicvoidspeak(){System.out.println("I run, run, run, but never get anywhere");}}
Map<String,Animal> animals = newHashMap<String,Animal>();
animals.put("dog",newDog());
animals.put("cat",newCat());
animals.put("hamster",newHamster());
for(Animal animal : animals){animal.speak();}
Solution 5:
Unfortunately, Java does not have first-class functions, but consider the following interface:
publicinterfaceF<A, B> {
public B f(A a);
}
This models the type for functions from type A
to type B
, as first-class values that you can pass around. What you want is a Map<String, F<A, B>>
.
Functional Java is a fairly complete library centered around first-class functions.
Post a Comment for "Java Equivalent Of Function Mapping In Python"