[英]Best way to pass arguments to a lambda in a hashmap in Java
我有一個接受不同命令的 CLI。 為了避免一個可擴展的長 switch 語句,我決定將我的命令放在一個哈希圖中,並有一個函數來檢查命令是否存在,如果存在則調用它。
public class Commands {
private LinkedHashMap<String, Runnable> commands = new LinkedHashMap<String, Runnable>();
public Commands(Scanner userInput) {
commands.put("foo", () -> this.foo());
commands.put("bar", () -> this.bar());
commands.put("foobar", () -> this.foobar());
... and so on
}
private void handleCommand(String command) {
if (!commands.containsKey(command)) {
System.out.printf("'%s' is an invalid command%n", command);
return;
}
commands.get(command).run();
}
public void foo() { ... }
public void bar() { ... }
public void foobar() { ... }
}
這創造了奇跡,我已經能夠快速添加大量命令。
我現在有一個問題,我的一些命令需要參數。 例如$ foo arg1 arg2
並且我想保留我最初以這種方式編寫的結構,因為我認為它很容易擴展。
我已經改變了我的 handleCommand() 方法,如下所示:
private void handleCommand(String command) {
// Split the command to get possible args
String[] args = command.split(" ");
if (!commands.containsKey(args[0])) { // the first string is the command we want
System.out.printf("'%s' is an invalid command%n", args[0]);
return;
}
commands.get(args[0]).run(Arrays.copyOfRange(args, 1, args.length));
}
並像這樣修改適當的方法
...
commands.put("foo", (args) -> this.foo(args));
...
public void foo(String[] args) { ... };
我也嘗試過使用我覆蓋run
的接口,我嘗試過使用 Callable 而不是 Runnable。 我現在不知道該嘗試什么。 我發現的很多例子比我需要的要復雜得多,我很難遵循它們。
我來自一個 javascript 背景,在那里完全可以做到:
obj = { foo: (args) => { ...do something with args } }
obj.foo(args)
所以這就是我為什么要這樣做的原因。
TIA
您可以使用Consumer
而不是Runnable
。 Consumer
接受一個參數並且不返回任何內容。 如果您還想返回一個參數,您需要使用Function
。 所以你的代碼看起來像這樣:
private LinkedHashMap<String, Consumer<String[]>> commands = new LinkedHashMap<>();
public Commands(Scanner userInput) {
commands.put("foo", this::foo); // with method reference. Its the same as next line
commands.put("bar", input -> this.bar(input));
commands.put("foobar", input -> this.foobar(input));
}
....
commands.get(command).accept(args); // Consumer's methods is accept
您可以在此處查看預定義的功能接口。
除了使用Consumer<String[]>
,您還可以為要實現的命令定義自定義接口:
public static interface Command {
public void run(String ... args);
}
要完全按照您的預期使用:
private LinkedHashMap<String, Command> commands = new LinkedHashMap<>();
commands.put("foo", (input) -> foo(input));
不要害怕聲明自己的特定接口。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.