I am working a small program which can receive several commands. Each of these commands should cause different methods to run. I was thinking that if there were a way to put all the methods into a HashMap and invoke them directly by getting the value paired with the command Key instead of using if statements, it could make things much simpler but as far as I understand this is not possible since methods aren't treated as objects in Java. Still, it will be educative to find out if there is a way to do this.
-
You've described the "Command Design Pattern" pretty well. Look it up and consider implementing it. – DontKnowMuchBut Getting Better Oct 13 '20 at 01:02
-
Have a look at this Q/A for more on this: [Using Command Design pattern](https://stackoverflow.com/questions/2015549/using-command-design-pattern) – DontKnowMuchBut Getting Better Oct 13 '20 at 01:04
-
@DontKnowMuchButGettingBetter I don't see how this answers my initial question about putting methods into HashMaps but that might just be my relative illiteracy in Java since I only started a few weeks ago. – random math student Oct 13 '20 at 01:24
2 Answers
Methods aren't objects (at least mostly not), but there is a concept that matches what you want: the functional interface, which is defined as an interface that has exactly one abstract method. Two out-of-the-box candidates are Runnable
, which takes no parameters, and Consumer
, which takes a single parameter and might be the best option if you want to pass in some kind of input (like a Scanner
). (If you also want a configurable output, BiConsumer
taking a Scanner
and a PrintWriter
might be suitable.)
Java has a convenience feature called method references that can automatically transform a method into an instance of a functional interface. Put together, it might look like this:
Map<String, Consumer<Scanner>> commands = new HashMap<>();
...
commands.put("foo", someCommand::go); // where someCommand is a variable with a go(Scanner) method
commands.put("bar", new OtherCommand());
commands.put("hello", unused -> { System.out.println("Hello!"); });
...
String commandName = scanner.next();
commands.get(commandName).accept(scanner);

- 75,269
- 21
- 115
- 152
This is not a good idea, make methods as hashmap value don't satisfied shell command complex scene, maybe you can use Runnable Object as value.
Another solution, you can use Spring Shell.
@ShellMethod("commandName")
public String doSomething(String param) {
return String.format("Hi %s", param);
}

- 1
- 3