Java 如何调用存储在 HashMap 中的方法?(爪哇)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4480334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call a method stored in a HashMap? (Java)
提问by cwhiii
I have a list of commands (i, h, t, etc) that the user will be entering on a command line/terminal Java program. I would like to store a hash of command/method pairs:
我有用户将在命令行/终端 Java 程序中输入的命令列表(i、h、t 等)。我想存储命令/方法对的散列:
'h', showHelp()
't', teleport()
So that I can have code something like:
这样我就可以有类似的代码:
HashMap cmdList = new HashMap();
cmdList.put('h', showHelp());
if(!cmdList.containsKey('h'))
System.out.print("No such command.")
else
cmdList.getValue('h') // This should run showHelp().
Is this possible? If not, what is an easy way to this?
这可能吗?如果没有,有什么简单的方法可以做到这一点?
采纳答案by aioobe
With Java 8+ and Lambda expressions
使用 Java 8+ 和 Lambda 表达式
With lambdas (available in Java 8+) we can do it as follows:
使用 lambdas(在 Java 8+ 中可用),我们可以这样做:
class Test {
public static void main(String[] args) throws Exception {
Map<Character, Runnable> commands = new HashMap<>();
// Populate commands map
commands.put('h', () -> System.out.println("Help"));
commands.put('t', () -> System.out.println("Teleport"));
// Invoke some command
char cmd = 't';
commands.get(cmd).run(); // Prints "Teleport"
}
}
In this case I was lazy and reused the Runnableinterface, but one could just as well use the Command-interface that I invented in the Java 7 version of the answer.
在这种情况下,我很懒惰并重用了Runnable接口,但也可以使用Command我在 Java 7 版本的答案中发明的-interface。
Also, there are alternatives to the () -> { ... }syntax. You could just as well have member functions for helpand teleportand use YourClass::helpresp. YourClass::teleportinstead.
此外,还有() -> { ... }语法的替代方案。您也可以为helpandteleport和使用YourClass::helpresp使用成员函数。YourClass::teleport反而。
A great Lambda cheat sheetover at Programming.Guide.
Oracle tutorial here: The Java Tutorials™ – Lambda Expressions.
Programming.Guide 上有一个很棒的Lambda 备忘单。
此处的 Oracle 教程:Java 教程™ – Lambda 表达式。
Java 7 and below
Java 7 及以下
What you really want to do is to create an interface, named for instance Command(or reuse for instance Runnable), and let your map be of the type Map<Character, Command>. Like this:
您真正想要做的是创建一个接口,命名为 instance Command(或重用 instance Runnable),并让您的地图的类型为Map<Character, Command>。像这样:
import java.util.*;
interface Command {
void runCommand();
}
public class Test {
public static void main(String[] args) throws Exception {
Map<Character, Command> methodMap = new HashMap<Character, Command>();
methodMap.put('h', new Command() {
public void runCommand() { System.out.println("help"); };
});
methodMap.put('t', new Command() {
public void runCommand() { System.out.println("teleport"); };
});
char cmd = 'h';
methodMap.get(cmd).runCommand(); // prints "Help"
cmd = 't';
methodMap.get(cmd).runCommand(); // prints "teleport"
}
}
Reflection "hack"
反射“黑客”
With that said, you canactually do what you're asking for (using reflection and the Methodclass.)
话虽如此,您实际上可以做您所要求的(使用反射和Method类。)
import java.lang.reflect.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
Map<Character, Method> methodMap = new HashMap<Character, Method>();
methodMap.put('h', Test.class.getMethod("showHelp"));
methodMap.put('t', Test.class.getMethod("teleport"));
char cmd = 'h';
methodMap.get(cmd).invoke(null); // prints "Help"
cmd = 't';
methodMap.get(cmd).invoke(null); // prints "teleport"
}
public static void showHelp() {
System.out.println("Help");
}
public static void teleport() {
System.out.println("teleport");
}
}
回答by Erich Kitzmueller
Though you could store methods through reflection, the usual way to do it is to use anonymous objects that wrap the function, i.e.
虽然您可以通过反射存储方法,但通常的方法是使用包装函数的匿名对象,即
interface IFooBar {
void callMe();
}
'h', new IFooBar(){ void callMe() { showHelp(); } }
't', new IFooBar(){ void callMe() { teleport(); } }
HashTable<IFooBar> myHashTable;
...
myHashTable.get('h').callMe();
回答by DVD
If you are using JDK 7 you can now use methods by lambda expression just like .net.
如果您使用的是 JDK 7,您现在可以像 .net 一样通过 lambda 表达式使用方法。
If Not the best way is to make a Function Object:
如果不是,最好的方法是创建一个函数对象:
public interface Action { void performAction(); }
Hashmap<string,Action> cmdList;
if(!cmdList.containsKey('h'))
System.out.print("No such command.") else cmdList.getValue('h').performAction();

