Java lambda中括号和箭头(->;)之间的变量是什么?

Java lambda中括号和箭头(->;)之间的变量是什么?,java,lambda,Java,Lambda,IDE推荐的修复程序生成了如下代码 col1.setCellValueFactory( (Callback<CellDataFeatures<String, String>, ObservableValue<String>>) param -> new SimpleObjectProperty<>(param.getValue().getValue()) );

IDE推荐的修复程序生成了如下代码

    col1.setCellValueFactory(
            (Callback<CellDataFeatures<String, String>, ObservableValue<String>>) param ->
                    new SimpleObjectProperty<>(param.getValue().getValue())
    );

PS:因为有人告诉我指定
col1
,所以它是JavaFX中类的对象

我想我被括号蒙蔽了,
param
没有括号,我认为括号里的就是参数。我原以为会有这样的形式


仔细检查,括号内的代码只是类型声明,而不是变量。。。当只有一个参数时,似乎可以省略参数的括号。

param
是传递给lambda的参数。此代码将帮助您了解正在发生的情况:

Function<String,String> s = (Function<String,String>) param -> {
    System.out.println(param);
    return param;
};
s.apply("Hello World");
函数s=(函数)参数->{
系统输出打印项次(参数);
返回参数;
};
s、 应用(“你好世界”);
上述代码不必要地将lambda强制转换为
(函数)


如果将其更改为
(函数)
,则会出现编译时错误。

您询问了
参数是什么,以及是否可以在其上搜索。您还询问了lambda表达式的“形式”(为什么有括号或没有括号)。我在下面的回答解决了这些问题

搜索文本
param
通常不起作用,因为文本
param
是任意的。。。您可以将其替换为
p
或甚至
任意名称
,只要lambda表达式中
->
右侧的名称更改为相同的值,代码仍应工作

您可以将
param
视为“传入”参数的名称。在下面的方法声明中有两个参数(
param
anotherParam

lambda表达式类似于方法声明(如上所述),但可以在lambda表达式的语法中删除不需要的文本。如果上面的可以生成Lambda表达式,它将如下所示:

    (String param, String anotherParam) -> { System.out.println(param+", "+anotherParam); }
请注意lambda表达式与方法声明有多么相似。还请注意,文本“myPrint”没有出现在上面。lambda表达式可以看作是一个“无名”的方法声明。在Java中,lambda表达式提供了在仅定义了一个抽象方法的接口中实现SingleAbstractMethod(SAM)的代码。假设您有一个定义为SAM名称的“MyPrint”接口,则不需要“MyPrint”(它是接口中唯一的抽象方法)。Lambda表达式之所以有效,是因为SAM接口是“功能接口”,Lambda表达式在功能接口中实现SAM。在lambda表达式中,始终不需要实现的方法名称。这是使lambda表达式难以理解的原因之一,因为您通常通过名称(在某种程度上)理解方法,并且您希望搜索lambda表达式正在实现的方法名称,但该名称不会出现在lambda代码中

上面的代码也可以写成

 (param, anotherParam) -> { System.out.println(param+", "+anotherParam); }
如果Java类型系统能够为自己确定参数类型(在本例中为
String
)。同样,名称
param
anotherParam
是任意的,但它们的类型不是。它们由SAM在使用lambda实现的功能接口中定义。lambda难以理解的另一个原因是参数的类型通常很有趣。。。但是lambda表达式通常不使用它,因为Java并不总是需要它

如果SAM只需要一个参数,那么lambda表达式可以如下所示编写

 (String param) -> { System.out.println(param); }
或者“字符串”是否可以由Java确定

 (param) -> { System.out.println(param); }
甚至在上一版本中也不需要
()

 param -> { System.out.println(param); }
还有其他一些简化。在某些情况下,如果
->
右侧的
{}
只是一个语句或表达式,则可以将其删除

如果正在实施的SAM中没有参数,则使用代码
()->
,其中
()
表示没有参数

关于lambda表达式,我要提到的最后一件很难理解的事情是可以进行大量语法简化(请参见以上所有内容)。这似乎是你困惑的主要原因

底线:可以将lambda表达式视为一个无名的方法声明,在该声明中,您将重写函数接口中的SAM。
->
的左侧是参数声明。。。参数类型甚至
()
并不总是需要的。
->
的右侧是方法的主体,在某些情况下不需要
{}


理解lambda表达式的关键是理解语法(所有上述形式),确定并理解正在实现的功能接口和SAM。不幸的是,函数接口或SAM的名称都没有显示在lambda表达式语法本身中。。。它被简化为不需要

param
是一个参数。您正在将lambda转换为
回调
对象,它是一个函数接口,实际上是一个SAM转换,实际上是接口回调中定义的var1中的param。您正在将一个回调重写调用函数的实现传递到setCellValueFactory()。@AnimeshSahu Java有点删除了SAM,并且只将lambda用于函数接口,而不是使用单个抽象方法的抽象类显示
col1
 (param) -> { System.out.println(param); }
 param -> { System.out.println(param); }