【问题标题】:How do I write this code without using Lambda and still have it work? [duplicate]如何在不使用 Lambda 的情况下编写此代码并且仍然可以正常工作? [复制]
【发布时间】:2020-05-18 19:44:59
【问题描述】:

我正在尝试在不使用 lambda 的情况下将此代码转换为工作,以便我可以更好地理解它,但我一点运气都没有。 ActionEvents 类似按钮怎么写?

enemyBoard = new Board(true, event -> {
    if (!running)
        return;

    Cell cell = (Cell) event.getSource();
    if (cell.wasShot)
        return;

    enemyTurn = !cell.shoot();

    if (enemyBoard.ships == 0) {
        System.out.println("YOU WIN");
        System.exit(0);
    }

    if (enemyTurn)
        enemyMove();
});

这里是Board 构造函数:

public Board(boolean enemy, EventHandler<? super MouseEvent> handler) {
    this.enemy = enemy;
    for (int y = 0; y < 10; y++) {
        HBox row = new HBox();
        for (int x = 0; x < 10; x++) {
            Cell c = new Cell(x, y, this);
            c.setOnMouseClicked(handler);
            row.getChildren().add(c);
        }

        rows.getChildren().add(row);
    }

    getChildren().add(rows);
}

代码属于战舰游戏,这里是游戏代码的链接:https://github.com/AlmasB/Battleship/tree/master/src/com/almasb/battleship

【问题讨论】:

  • lambda 表达式 只是接口的实现。你将如何在不使用 lambda 的情况下实现接口 EventHandler&lt;? super MouseEvent&gt;? [提示:写一个类,例如public class G implements EventHandler&lt;? super MouseEvent&gt;] 剩下的可以填吗?
  • 也许你应该找到不使用 lambdas 的战舰代码。把你不懂的代码放到网上,然后让别人帮你简化,这不是 StackOverflow 的真正目的。

标签: java lambda actionevent


【解决方案1】:
enemyBoard = new Board(true, event -> {
    ...
});

lambda 是实现functional interface 的简写方式,它是一个带有单个(非default)方法的interface。没有 lambda 的等效代码是:

enemyBoard = new Board(true, new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        ...
    }
});

就是这样。它只是用于实例化匿名 EventHandler 并实现其单个 handle() 方法的语法糖

我省略了方法主体,因为它在两者中都是相同的。

如果这看起来仍然很奇怪,那么写 new ClassOrInterface() { ... } 本身也是一种语法糖。我们可以应用另一轮去糖并显式写出匿名类:

class EventHandler$1 implements EventHandler<MouseEvent> {
    public void handle(MouseEvent event) {
        ...
    }
}
enemyBoard = new Board(true, new EventHandler$1());

请注意,EventHandler$1 是一个自动生成的类名,保证不会与任何其他真实类发生冲突。编译器使用$ 字符(在最终用户代码中是不合法的)来命名类,使其不会发生冲突。如果您曾经在堆栈跟踪中看到带有美元符号的类名,那就是它们的来源:匿名类。

 

作为@user points out,它实际上更复杂。 Lambdas 并不总是对匿名类脱糖。通常编译器可以做一些更有效的事情。但从概念上讲,将它们视为匿名类是一种在心理上翻译它们的好方法。

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 2014-04-20
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 2021-06-08
    相关资源
    最近更新 更多