Storing/executing 代码片段作为 Java 中的变量

Storing/executing code fragments as variables in Java

我正在尝试创建一个基于控制台的菜单 class。我希望 class 包含 MenuOption 对象的数组(命名选项),每个对象都有一个标签 (String)、文本 (String) 和代码 (TBD) 属性。我的想法是,我希望用户输入一个字符串,然后菜单将执行与以下内容接近的相关代码:

for (MenuOption option: options)
{
如果 (input.equals(option.label)) 执行 option.code;
}

我觉得可能有一种使用 lambda 函数来执行此操作的方法,但在过去的几个小时里我一直在走入死胡同。任何建议表示赞赏。

你走在正确的轨道上。尝试类似的东西:

public record MenuOption(String label,
                         String text,
                         Runnable action) {
    // Deliberately empty.
}

如您所料,您可以使用 lambda 构造它们:

MenuOption printOption = new MenuOption(
    "Print",
    "Send formatted data to a printer",
    () -> printData());

MenuOption exitOption = new MenuOption(
    "Exit",
    "Close application",
    () -> System.exit(0));

如果你受困于旧版本的 Java,你可以制作一个普通的 class,相当于一条记录:

public class MenuOption {
    private String label;
    private String text;
    private Runnable action;

    public MenuOption(String label,
                      String text,
                      Runnable action) {
        this.label = label;
        this.text = text;
        this.action = action;
    }

    public String getLabel() {
        return label;
    }

    public String getText() {
        return text;
    }

    public Runnable getAction() {
        return action;
    }
}

这是经典的 Java 8+ 版本,完全实现。

package Whosebug;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Objects;

public class ConsoleMenu {

    static public class MenuOption {
        public final String     label;
        public final String     text;
        public final Runnable   code;
        public MenuOption(final String pLabel, final String pText, final Runnable pLambda) {
            label = pLabel;
            text = pText;
            code = pLambda;
        }
    }



    public static void main(final String[] args) throws IOException {
        final ArrayList<MenuOption> options = new ArrayList<>();
        options.add(new MenuOption("Option A", "A", () -> System.out.println("Hello this is A")));
        options.add(new MenuOption("Option B", "B", () -> {
            System.out.print("Hello this is B");
            System.out.println(" in multiple lines Lambda");
        }));


        System.out.println(" - - - Menu - - - ");
        for (final MenuOption mo : options) {
            System.out.println("\t" + mo.label + "\t" + mo.text);
        }
        System.out.println("Enter your choice:");
        try (final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));) {
            final String line = br.readLine().toLowerCase();
            for (final MenuOption mo : options) {
                if (Objects.equals(line, mo.text.toLowerCase())) {
                    System.out.println("You chose " + mo.label);
                    mo.code.run();
                    break;
                }
            }
        }

        System.out.println("All done.");
    }

}