web-dev-qa-db-ja.com

HashMapに保存されたメソッドを呼び出す方法は? (Java)

ユーザーがコマンドライン/ターミナルで入力するコマンドのリスト(i、h、tなど)がありますJavaプログラム。コマンド/メソッドのハッシュを保存したいペア:

'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().

これは可能ですか?そうでない場合、これへの簡単な方法は何ですか?

50
cwhiii

With Java 8+および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-インターフェースを使用することもできます答えの。

また、() -> { ... }構文に代わるものがあります。 helpteleportのメンバー関数を使用して、YourClass::help respを使用することもできます。代わりに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"

    }
}

リフレクション「ハック」

そうは言っても、あなたはcan実際にあなたが求めていることを行う(リフレクションと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");
    }
}
101
aioobe

リフレクションを介してメソッドを保存することもできますが、通常の方法では、関数をラップする匿名オブジェクトを使用します。

  interface IFooBar {
    void callMe();
  }


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

 HashTable<IFooBar> myHashTable;
 ...
 myHashTable.get('h').callMe();
5

JDK 7を使用している場合、.netのようにラムダ式によるメソッドを使用できます。

最良の方法ではない場合は、関数オブジェクトを作成します。

public interface Action {    void performAction(); }

Hashmap<string,Action> cmdList;

if(!cmdList.containsKey('h'))
    System.out.print("No such command.") else    cmdList.getValue('h').performAction();
4
DVD