一尘不染

Java 如何调用存储在HashMap中的方法?

java

我有用户将在命令行/终端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.getValue('h')   // This should run showHelp().

这可能吗?如果没有,那么简单的方法是什么?


阅读 307

收藏
2020-03-23

共1个答案

一尘不染

使用Java 8+和Lambda表达式
使用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接口,但是也可以使用Command我在答案的Java 7版本中发明的-interface

此外,() -> { ... }语法还有其他选择。你也可以具有和的成员函数help,teleport并使用YourClass::helprespYourClass::teleport代替。

  • Programming.Guide上有一篇很棒的Lambda备忘单。
  • 此处的Oracle教程:Java教程™– Lambda表达式。

Java 7及以下
你真正想要做的是创建一个接口Command(例如命名)(或例如重用Runnable),然后让你的地图成为type Map。像这样:

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"

话虽如此,你实际上可以完成你所要的工作(使用反射和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");
    }
}
2020-03-23