Java 如何调用HashMap中存储的方法?(爪哇)
我有一个用户将在命令行/终端Java程序中输入的命令列表(I、h、t等)。我想存储命令/方法对的散列:Java 如何调用HashMap中存储的方法?(爪哇),java,hash,methods,invoke,Java,Hash,Methods,Invoke,我有一个用户将在命令行/终端Java程序中输入的命令列表(I、h、t等)。我想存储命令/方法对的散列: 'h', showHelp() 't', teleport() 这样我就可以编写如下代码: HashMap cmdList = new HashMap(); cmdList.put('h', showHelp()); if(!cmdList.containsKey('h')) System.out.print("No such command.") else cmdList.
'h', showHelp()
't', teleport()
这样我就可以编写如下代码:
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().
这可能吗?如果不是,那么什么是一种简单的方法呢?尽管可以通过反射存储方法,但通常的方法是使用包装函数的匿名对象,即
interface IFooBar {
void callMe();
}
'h', new IFooBar(){ void callMe() { showHelp(); } }
't', new IFooBar(){ void callMe() { teleport(); } }
HashTable<IFooBar> myHashTable;
...
myHashTable.get('h').callMe();
接口IFooBar{
无效callMe();
}
'h',新的IFooBar(){void callMe(){showHelp();}
't',新的IFooBar(){void callMe(){teleport();}}
哈希表myHashTable;
...
myHashTable.get('h').callMe();
使用Java 8+和Lambda表达式
使用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"
}
}
反射“黑客”
话虽如此,您实际上可以做您要求的事情(使用反射和方法
类)
import java.lang.reflect.*;
导入java.util.*;
公开课考试{
公共静态void main(字符串[]args)引发异常{
Map methodMap=newhashmap();
methodMap.put('h',Test.class.getMethod(“showHelp”);
methodMap.put('t',Test.class.getMethod('teleport');
char cmd='h';
methodMap.get(cmd.invoke(null);//打印“帮助”
cmd='t';
methodMap.get(cmd.invoke(null);//打印“传送”
}
公共静态void showHelp(){
System.out.println(“帮助”);
}
公共静态void传送(){
System.out.println(“传送”);
}
}
如果您使用的是JDK 7,您现在可以像.net一样使用lambda表达式的方法
如果不是,最好的方法是创建函数对象:
public interface Action { void performAction(); }
Hashmap<string,Action> cmdList;
if(!cmdList.containsKey('h'))
System.out.print("No such command.") else cmdList.getValue('h').performAction();
公共接口操作{void performAction();}
Hashmap-cmdList;
如果(!cmdList.containsKey('h'))
System.out.print(“无此命令”)else cmdList.getValue('h').performAction();
不支持一级函数真是讨厌:)我认为这是线程安全的,但我不确定您是否同意这是线程安全的。我怀疑get
操作是线程安全的。但为了确保您可能希望使用集合。synchronizedMap
@9000,答案已更新:-)@如果我的问题很愚蠢的话,我很抱歉,但是Java 8的第一个示例的运行时是什么实际上,lambda表达式被推迟到JDK 8。我只是想知道,使用哈希映射代替ho-hum开关有什么好处?因为没有人想记住命令87是“eat”事实上,我可以将命令、帮助文本等简单地关联在一起。
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");
}
}
public interface Action { void performAction(); }
Hashmap<string,Action> cmdList;
if(!cmdList.containsKey('h'))
System.out.print("No such command.") else cmdList.getValue('h').performAction();