[英]Java equivalent of function mapping in Python
In python, if I have a few functions that I would like to call based on an input, i can do this: 在python中,如果我有一些我想根据输入调用的函数,我可以这样做:
lookup = {'function1':function1, 'function2':function2, 'function3':function3}
lookup[input]()
That is I have a dictionary of function name mapped to the function, and call the function by a dictionary lookup. 那就是我有一个映射到该函数的函数名字典,并通过字典查找来调用该函数。
How to do this in java? 如何在java中执行此操作?
Java doesn't have first-class methods, so the command pattern is your friend... Java没有一流的方法,所以命令模式是你的朋友......
disclamer: code not tested! disclamer:代码未经测试!
public interface Command
{
void invoke();
}
Map<String, Command> commands = new HashMap<String, Command>();
commands.put("function1", new Command()
{
public void invoke() { System.out.println("hello world"); }
});
commands.get("function1").invoke();
There are several ways to approach this problem. 有几种方法可以解决这个问题。 Most of these were posted already: 其中大部分已经发布:
Personally I would use the Command approach. 我个人会使用Command方法。 Commands combine well with Template Methods , allowing you to enforce certain patterns on all your command objects. 命令与模板方法完美结合,允许您在所有命令对象上强制执行某些模式。 Example: 例:
public abstract class Command {
public final Object execute(Map<String, Object> args) {
// do permission checking here or transaction management
Object retval = doExecute(args);
// do logging, cleanup, caching, etc here
return retval;
}
// subclasses override this to do the real work
protected abstract Object doExecute(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. 例如,您无法通过为每个方法创建命令来在命令shell中公开Java API。
You could use a Map<String,Method> or Map<String,Callable> etc,and then use map.get("function1").invoke(...). 您可以使用Map <String,Method>或Map <String,Callable>等,然后使用map.get(“function1”)。invoke(...)。 But usually these kinds of problems are tackled more cleanly by using polymorphism instead of a lookup. 但通常使用多态而不是查找来更清晰地解决这些问题。
Polymorphic example.. 多态的例子..
public interface Animal {public void speak();};
public class Dog implements Animal {public void speak(){System.out.println("treat? treat? treat?");}}
public class Cat implements Animal {public void speak(){System.out.println("leave me alone");}}
public class Hamster implements Animal {public void speak(){System.out.println("I run, run, run, but never get anywhere");}}
Map<String,Animal> animals = new HashMap<String,Animal>();
animals.put("dog",new Dog());
animals.put("cat",new Cat());
animals.put("hamster",new Hamster());
for(Animal animal : animals){animal.speak();}
Unfortunately, Java does not have first-class functions, but consider the following interface: 遗憾的是,Java没有一流的功能,但请考虑以下界面:
public interface F<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. 这会为类型A
到类型B
函数类型建模,作为可以传递的第一类值。 What you want is a Map<String, F<A, B>>
. 你想要的是Map<String, F<A, B>>
。
Functional Java is a fairly complete library centered around first-class functions. Functional Java是一个以一流函数为中心的相当完整的库。
As mentioned in other questions, a Map<String,MyCommandType>
with anonymous inner classes is one verbose way to do it. 正如其他问题中所提到的,具有匿名内部类的Map<String,MyCommandType>
是一种冗长的方法。
A variation is to use enums in place of the anonymous inner classes. 一种变体是使用枚举代替匿名内部类。 Each constant of the enum can implement/override methods of the enum or implemented interface, much the same as the anonymous inner class technique but with a little less mess. 枚举的每个常量都可以实现/覆盖枚举或实现接口的方法,与匿名内部类技术非常相似,但是稍微少一些。 I believe Effective Java 2nd Ed deals with how to initialise a map of enums. 我相信Effective Java 2nd Ed处理如何初始化枚举地图。 To map from the enum name merely requires calling MyEnumType.valueOf(name)
. 要从枚举名称映射,只需要调用MyEnumType.valueOf(name)
。
As everyone else said, Java doesn't support functions as first-level objects. 正如其他人所说,Java不支持作为第一级对象的功能。 To achieve this, you use a Functor, which is a class that wraps a function. 要实现此目的,请使用Functor,它是一个包装函数的类。 Steve Yegge has a nice rant about that. 史蒂夫·耶格对此有一个很好的咆哮 。
To help you with this limitation, people write functor libraries: jga , Commons Functor 为了帮助您解决这个限制,人们编写了函子库: jga , Commons Functor
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.