How to call a method stored in a HashMap? (Java) [duplicate]

社会主义新天地 提交于 2019-11-26 15:01:48

With Java 8+ and Lambda expressions

With lambdas (available in Java 8+) we can do it as follows:

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.

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.


Java 7 and below

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:

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 can actually do what you're asking for (using reflection and the Method class.)

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");
    }
}

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();

If you are using JDK 7 you can now use methods by lambda expression just like .net.

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();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!