Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to do a minor refactor using lambdas in Java

I am working on part of a program (concerning speech recognition and a remote control car), where the code transmit(XXXXX); disableAutoMode(); is repeated many times. For curiosity's sake I would like to convert this into a lambda function similar to this var f = p -> transmit(p); disableAutoMode(); (forgive the var; I don't know what the type of the expression would be) and then call it in a way similar to this: f("s");, f("a"); and f("f"); or something similar to f.call("s");, f.call("a"); and f.call("f");.

What is the correct syntax to use a simple lambda function in Java similar to how I described above? (What should I put down as it's type instead of saying var?)

Here is the block of code, if you're curious:

@Override
public void onResult(Hypothesis hypothesis) {
    if (hypothesis != null) {
        String text = hypothesis.getHypstr();
        Log.i("onresult",text);
        ToastMaster(text);

        switch (text) {
            case "forward":
            case "go forward":
                transmit("f");
                disableAutoMode();
                break;
            case "go back":
            case "go backward":
            case "back":
            case "backward":
            case "reverse":
                transmit("b");
                disableAutoMode();
                break;
            case "skid left":
            case "go left":
                transmit("l");
                disableAutoMode();
                break;
            case "skid right":
            case "go right":
                transmit("r");
                disableAutoMode();
                break;
            case "turn left":
                transmit("q");
                disableAutoMode();
                break;
            case "turn right":
                transmit("e");
                disableAutoMode();
                break;
            case "reverse left":
                transmit("z");
                disableAutoMode();
                break;
            case "reverse right":
                transmit("x");
                disableAutoMode();
                break;
            case "stop":
                disableAutoMode();
                break;
            case "automatic":
                toggleAutoMode(null);
                break;
            case "enable automatic mode":
                enableAutoMode();
                break;
            case "disable automatic mode":
                disableAutoMode();
                break;
        }
    }
}
like image 247
TheIronKnuckle Avatar asked Feb 04 '26 12:02

TheIronKnuckle


2 Answers

A more ambitious refactoring would build on the "turn code into data" principle that lambdas are all about, turning your switch statement from code to data as well. How about:

// One-time setup of the machine
Map<String, Consumer<String>> actions = new HashMap<>();
actions.put("go forward", x -> { transmit(x); disableAutoMode(); });
actions.put(...)
...

public void onResult(Hypothesis hypothesis) {
    if (hypothesis != null) {
        String text = hypothesis.getHypstr();
        Log.i("onresult",text);
        ToastMaster(text);

        Consumer<String> action = actions.get(text);
        if (action != null)
            action.accept(text);
    }
}
like image 99
Brian Goetz Avatar answered Feb 07 '26 00:02

Brian Goetz


In this case you want a Consumer.

Consumer<String> function = (x) -> { transmit(x); disableAutoMode(); };
function.accept("hello!");

However I'm not sure why you want to use a lambda expression here, you could just create a plain old method and call that.

If you are after a more meaningful refactor one option would be to switch to a map of String, Action/Runnable. While you would end up with more code, the goal of refactors is not to "make it smaller" but to make it more readable/maintainable. By splitting each action into its own small self-contained class each action can be tested in isolation with minimal set-up. Each action can be reused (as it is just a class). With a good naming strategy it would be obvious to readers what is going on without having to dig through a large switch statement.

like image 39
Michael Lloyd Lee mlk Avatar answered Feb 07 '26 02:02

Michael Lloyd Lee mlk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!