如何调用存储在HashMap中的方法?(JAVA)

cwh*_*iii 51 java methods hash invoke

我有一个命令列表(i,h,t等),用户将在命令行/终端Java程序中输入.我想存储一个命令/方法对的哈希:

'h', showHelp()
't', teleport()
Run Code Online (Sandbox Code Playgroud)

所以我可以使用类似的代码:

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().
Run Code Online (Sandbox Code Playgroud)

这可能吗?如果没有,这是一个简单的方法吗?

aio*_*obe 102

使用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"
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我很懒,并重用了Runnable界面,但也可以使用Command我在Java 7版本的答案中发明的接口.

此外,还有() -> { ... }语法的替代方案.你可能也同样有成员函数helpteleport和使用YourClass::helpRESP.YourClass::teleport代替.


Java 7及以下版本

你真正想要做的是创建一个以实例命名的接口Command(或者例如重用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"

    }
}
Run Code Online (Sandbox Code Playgroud)

反思"黑客"

话虽如此,你实际上可以做你想要的(使用反射和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");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不支持一流的功能是如此令人讨厌:) (7认同)

Eri*_*ler 5

虽然您可以通过反射存储方法,但通常的方法是使用包装函数的匿名对象,即

  interface IFooBar {
    void callMe();
  }


 'h', new IFooBar(){ void callMe() { showHelp(); } }
 't', new IFooBar(){ void callMe() { teleport(); } }

 HashTable<IFooBar> myHashTable;
 ...
 myHashTable.get('h').callMe();
Run Code Online (Sandbox Code Playgroud)