【问题标题】:Writing a lambda expression when parameters are ignored in the body在正文中忽略参数时编写 lambda 表达式
【发布时间】:2016-06-02 16:49:43
【问题描述】:

如果 lambda 表达式不需要参数,因此名称过多,我该如何编写?

这种方式不编译:

setRowFactory(-> new TableRowCustom());

但是这个可以:

setRowFactory(__ -> new TableRowCustom());

有没有更好的办法?

【问题讨论】:

  • setRowFactory的参数所期望的功能接口类型(和方法)是什么?
  • 你也可以使用 TableRowCustom::new 的方法引用,它是 lambda 的替代品
  • @george,您不能使用方法引用来引用不采用与目标函数类型相同数量的参数的方法(显然这里是 0 对 1)。
  • @george 他的构造函数没有参数,而且预期的接口显然是带一个的(正如他所说,它是用__ 编译的),所以它不可能是一个简单的Supplier。事实上,我认为通过谷歌搜索方法名称可能是 JavaFX Callback,参见 TableView#setRowFactory(Callback)
  • @george:只使用构造函数引用而不考虑意外的函数参数可能会导致类似“Horrendous performance & large heap footprint of Java 8 constructor reference”

标签: java lambda java-8


【解决方案1】:

既然你提到这行得通

setRowFactory(__ -> new TableRowCustom());

我假设预期的函数式接口方​​法必须接受单个参数。 The identifier _ is a reserved keyword since Java 8.

我只会使用一次性的单个(有效标识符)字符。

setRowFactory(i -> new TableRowCustom());
setRowFactory($ -> new TableRowCustom()); 

虽然,您应该避免使用$,Java 语言规范states

美元符号应仅用于机械生成的源代码,或者很少用于访问遗留系统上预先存在的名称。下划线可以用在由两个或多个字符组成的标识符中,但由于是关键字,它不能用作一个字符的标识符。

你也可以写出来

setRowFactory(ignored -> new TableRowCustom());

要明确。

Java Language Specification 定义了 lambda 表达式的语法

LambdaExpression:
  LambdaParameters -> LambdaBody 

LambdaParameters:
  Identifier
  ( [FormalParameterList] )
  ( InferredFormalParameterList )
InferredFormalParameterList:
  Identifier {, Identifier}

换句话说,您不能省略标识符。


正如Holger 建议的那样,如果当他们决定使用_ 作为未使用的参数名称时,很容易在您的源代码中从__ 更改为_。您现在可能只想坚持下去。

【讨论】:

  • 我不会反对将__ 用于不必要的参数,因为显然单个_ 是保留的,因为它旨在成为将来未使用参数的一次性标识符。发生这种情况时,将 __ -> expression 更改为 _ -> expression 不会有什么大不了的。
  • 不幸的是 __ 与 python 占位符的工作方式不同,因为(__,__,whatIcareAbout) 导致java: variable __ is already defined in method 错误。忽略1,忽略2可能更可取
  • 使用(__,___,whatIcareAbout) then...目前不是最佳选择,但它清楚地表明了目的。
  • 为什么要“避免”使用美元符号?我知道这是一个用于生成代码的特殊标识符,但是除了简单的命名法之外,它是否代表了一些特殊情况或应该避免使用它的原因?
  • @niken 不,差不多,我已经添加了 JLS 的注释来澄清评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2023-03-29
  • 2021-10-28
  • 2012-03-28
相关资源
最近更新 更多