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 Runnable
interface, 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 help
and teleport
and use YourClass::help
resp. YourClass::teleport
instead.
此外,还有() -> { ... }
语法的替代方案。您也可以为help
andteleport
和使用YourClass::help
resp使用成员函数。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 Method
class.)
话虽如此,您实际上可以做您所要求的(使用反射和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();