我对Lisp中的lambda函数有很好的理解。 Java似乎没有Lisp那样的灵活性。我如何在Java中考虑lambdas? 鉴于下面的代码,我该怎么做?
public class Draw {
GraphicsContext gc;
static void draw(double x, double y, double w, double h, boolean drawRect) {
if (drawRect) {
gc.fillRect(x, y, w, h);
} else {
gc.strokeRect(x, y, w, h);
}
}
// How do I do that?
static void drawWithLambda(double x, double y, double w, double h /**, lambda */) {
lambda(x, y, w, h);
}
public static void main(String[] args) {
draw(0, 0, 50, 50, false); // OK
drawWithLambda(0, 0, 50, 50, GraphicsContext::fillRect); // Ok?
}
}
答案 0 :(得分:3)
您必须指定lambda
方法参数实现的功能接口的类型:
drawWithLambda(double x, double y, double w, double h, SomeFuncInterface lambda) {
lambda.someMethod (x, y, w, h); // someMethod is the single method that
// SomeFuncInterface implements
}
为了让这条线路正常工作
drawWithLambda(0, 0, 50, 50, GraphicsContext::fillRect);
fillRect
的方法GraphicsContext
必须与SomeFuncInterface
功能界面的方法签名兼容。
BTW,GraphicsContext::fillRect
是方法引用,而不是lambda表达式。您可以传递lambda表达式,方法引用或函数接口的任何其他实现(常规类实例,匿名类实例等)。
答案 1 :(得分:3)
Java中的Lambda与functional interface的概念结合使用。
典型的例子是Function
。 Function
是一个功能接口,其功能方法apply
是一个接受单个参数并返回结果的方法。
您可以创建自己的功能界面,谁将定义一个带有4个参数且没有返回类型的函数方法,如下所示:
@FunctionalInterface
interface RectangleDrawer {
void draw(double x, double y, double w, double h);
}
(FunctionalInterface
注释并非绝对必要,但它有明确的意图。)
然后,您可以创建符合此功能接口合约的lambda。典型的lambda syntax是(method arguments) -> (lambda body)
。在此示例中,它将是:(x, y, w, h) -> gc.fillRect(x, y, w, h)
。这是因为lambda声明了4个参数并且没有返回类型,所以它可以表示为之前定义的RectangleDrawer
的函数方法。
你的例子将成为:
static GraphicsContext gc;
public static void main(String[] args) {
draw(0, 0, 50, 50, (x, y, w, h) -> gc.fillRect(x, y, w, h));
draw(0, 0, 50, 50, (x, y, w, h) -> gc.strokeRect(x, y, w, h));
}
static void draw(double x, double y, double w, double h, RectangleDrawer drawer) {
drawer.draw(x, y, w, h);
}
在这种特殊情况下,可以使用method reference创建lambda,使用::
运算符,它允许编写更简单的代码:
static GraphicsContext gc;
public static void main(String[] args) {
draw(0, 0, 50, 50, gc::fillRect);
draw(0, 0, 50, 50, gc::strokeRect);
}
static void draw(double x, double y, double w, double h, RectangleDrawer drawer) {
drawer.draw(x, y, w, h);
}