如何调用存储在HashMap中的方法? (Java)
我有一个命令列表(我,H,T等),用户将在命令行/terminalJava程序中input。 我想存储一个命令/方法对的散列:
'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().
这可能吗? 如果没有,这是一个简单的方法?
使用Java 8+和Lambdaexpression式
使用lambda(可用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" } }
在这种情况下,我很懒惰,重用了Runnable
接口,但是也可以使用我在Java 7版本中发明的Command
接口。
另外,还有() -> { ... }
语法的替代方法。 你也可以有help
和teleport
成员函数,并使用YourClass::help
。 YourClass::teleport
代替。
-
在Programming.Guide一个伟大的Lambda作弊表 。
-
Oracle教程在这里: Java Tutorials™ – Lambdaexpression式 。
Java 7及以下版本
你真正想做的是创build一个接口,命名为实例Command
(或重用实例Runnable
),让你的地图的types为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和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"); } }
尽pipe可以通过reflection来存储方法,但通常的做法是使用包装函数的匿名对象
interface IFooBar { void callMe(); } 'h', new IFooBar(){ void callMe() { showHelp(); } } 't', new IFooBar(){ void callMe() { teleport(); } } HashTable<IFooBar> myHashTable; ... myHashTable.get('h').callMe();
如果您正在使用JDK 7,则可以像使用.net一样使用lambdaexpression式的方法。
如果不是最好的方法是创build一个函数对象:
public interface Action { void performAction(); } Hashmap<string,Action> cmdList; if(!cmdList.containsKey('h')) System.out.print("No such command.") else cmdList.getValue('h').performAction();