我有以下课程
public class Envirionment {
private Square[][] grid;
public Envirionment(int width, int height) {
this.grid = new Square[height][width];
}
public void map(SquareActor actor) {
for(int y = 0; y < grid.length; y++) {
for(int x = 0; x < grid[y].length; x++) {
actor.act(grid[y][x]);
}
}
}
}
为了测试map
方法是否正常工作,我开始构建测试,测试的目的是传递一个可以作用于平方的函数,并查看其是否正常工作。
此测试的主要部分之一是确保它实际上遍历了所有平方,因此我认为我可以传递一个函数,该函数可以绑定到以下变量的x
和y
变量循环,并使用值为x
和y
的回调函数,并在测试中保留一个本地计数器以进行比较和对比。
我从测试开始,看看是否可以传入一个只打印出x
和y
变量的函数,但是我遇到了第一个障碍。
class EnvirionmentTest {
@Test
void test() {
Envirionment env = new Envirionment(10, 10);
env.map((square) -> System.out.println(String.format("%d, %d", x, y)));
fail("Not yet implemented");
}
}
结果是,编译器开始大吼大叫,因为x
和y
无法解析为变量,但是我认为这些将绑定到将在其中调用的循环范围。
是否可以在Java中设置这些变量的绑定?还是我完全没有解决这个问题?
编辑:
我刚刚在python中尝试了类似的方法,而且看起来工作正常。
test = lambda : print(str(x) + "," str(y))
for y in range(2):
for x in range(2):
test()
输出:
0,0
1,0
0,1
1,1
答案 0 :(得分:1)
在Square类中,您可以将这些x和y值定义为局部变量,然后使用如下所示的lambda函数:
env.map((square) -> System.out.println(String.format("%d, %d", square.x, square.y)));
答案 1 :(得分:1)
在您的python示例中,您创建了lambda表达式,该表达式与Java中的等效:
BiConsumer<String, String> biFunction = (x, y) -> System.out.println(x + "," + y);
在您的示例中,您收到编译错误,因为在此表达式中:
env.map((square) -> System.out.println(String.format("%d, %d", x, y)));
编译器不知道x
和y
是什么,他是正确的。
您的Environment::map
方法采用类型SquareActor
的参数。您正在将lambda表达式传递给Environment::map
,它将作为实现SquareActor
的匿名类实例(必须为FunctionalInterface
的实例)进行解析。在您的情况下,您的lambda表达式必须看起来像
env.map((square, x, y) -> System.out.println(String.format("%d, %d", x, y)));
,但是它与SquareActor::act
方法签名不匹配。 Java不支持您认为的闭包。如果您想知道如何在Java中实现闭包,请查看this article。
您的Environment::map
方法仅循环遍历内部数组,并将参数传递给SquareActor::act
。因此,您不应该访问SquareActor::act
内部的本地循环计数器吗?如果您想测试您的方法,则只想检查您的“模拟”实现是否应被触发多次:
env.map(square -> System.out.println(String.format("Square " + square)));
应该足够了(如果您为toString
类重写了Square
方法。