如何在不使用 Lambda 的情况下编写此代码并使其仍然有效?
How do I write this code without using Lambda and still have it work?
我试图将此代码转换为在不使用 lambda 的情况下工作,以便我可以更好地理解它,但我一点运气都没有。怎么写成类似按钮的ActionEvent
?
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);
}
该代码属于战舰游戏,这里是link游戏代码:https://github.com/AlmasB/Battleship/tree/master/src/com/almasb/battleship.
enemyBoard = new Board(true, event -> {
...
});
lambda 是 shorthand 实现 functional interface 的方法,它是一个 interface
和一个(非 default
)方法。没有 lambda 的等效代码是:
enemyBoard = new Board(true, new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
...
}
});
就是这样。它只是语法糖 † 用于实例化匿名 EventHandler
并实现其单个 handle()
方法。
我省略了方法体,因为两者是一样的。
如果这看起来仍然很奇怪,写 new ClassOrInterface() { ... }
本身也是一种语法糖。我们可以应用另一轮脱糖并显式写出匿名 class:
class EventHandler implements EventHandler<MouseEvent> {
public void handle(MouseEvent event) {
...
}
}
enemyBoard = new Board(true, new EventHandler());
请注意 EventHandler
是一个自动生成的 class 名称,保证不会与任何其他真实的 class 冲突。编译器使用 $
字符来命名 class,这在最终用户代码中是不合法的,这样就不会发生冲突。如果您曾经在堆栈跟踪中看到 class 带有美元符号的名称,这就是它们的来源:匿名 classes.
† 和一样,背后其实更复杂。 Lambda 并不总是对匿名 class 脱糖。通常编译器可以做一些更有效率的事情。但从概念上讲,将它们视为匿名的 classes 是在心理上翻译它们的好方法。
我试图将此代码转换为在不使用 lambda 的情况下工作,以便我可以更好地理解它,但我一点运气都没有。怎么写成类似按钮的ActionEvent
?
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);
}
该代码属于战舰游戏,这里是link游戏代码:https://github.com/AlmasB/Battleship/tree/master/src/com/almasb/battleship.
enemyBoard = new Board(true, event -> { ... });
lambda 是 shorthand 实现 functional interface 的方法,它是一个 interface
和一个(非 default
)方法。没有 lambda 的等效代码是:
enemyBoard = new Board(true, new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
...
}
});
就是这样。它只是语法糖 † 用于实例化匿名 EventHandler
并实现其单个 handle()
方法。
我省略了方法体,因为两者是一样的。
如果这看起来仍然很奇怪,写 new ClassOrInterface() { ... }
本身也是一种语法糖。我们可以应用另一轮脱糖并显式写出匿名 class:
class EventHandler implements EventHandler<MouseEvent> {
public void handle(MouseEvent event) {
...
}
}
enemyBoard = new Board(true, new EventHandler());
请注意 EventHandler
是一个自动生成的 class 名称,保证不会与任何其他真实的 class 冲突。编译器使用 $
字符来命名 class,这在最终用户代码中是不合法的,这样就不会发生冲突。如果您曾经在堆栈跟踪中看到 class 带有美元符号的名称,这就是它们的来源:匿名 classes.
† 和