将Java方法转换为kotln。返回一个lambda表达式

时间:2019-06-22 18:33:27

标签: java kotlin

/

我有以下Java代码段,试图将其转换为Kotlin

kotlin 1.3.31

我对上述方法的不了解是一个方法声明,该声明以ArgumentMatcher作为返回类型,并且接口的方法在lambda表达式中执行,并返回生成的布尔值。如果我的解释有误,请纠正我。

但是,当我尝试将其转换为Kotlin

private ArgumentMatcher<List<Person> customArgumentMatcher(final int size) {
    return argument -> argument.size() == size;
}

我收到以下错误:

 private fun customArgumentMatcher(size: Int): ArgumentMatcher<List<Person>> {
    return { argument -> argument.size == size }
 }

非常感谢您的任何建议,

2 个答案:

答案 0 :(得分:4)

为其他答案添加背景:

就Java互操作性而言,这是Kotlin中稍显尴尬的领域之一。但这是Kotlin本身就是一种更好的语言的不幸结果!我来解释一下...

当Java添加了lambda时,他们以某种方式(与之前的泛型一样)做到了这一点,以最小程度地改变了语言的工作方式。因此,他们没有使函数成为一流的类型。相反,他们奉行使用接口的现有做法。例如,如果您希望将ActionEvent的信息告知您,则可以实现ActionListener接口。这有一个称为actionPerformed()的方法,它带有一个ActionEvent参数。

他们不想更改任何方法的工作方式,因此在Java 8+中,lambda只是实现某些接口的一种更为简洁的方法。上下文(即您正在调用的方法,或您要为其分配的变量的类型)告诉编译器您想要哪种类型的接口,它必须是具有单一抽象方法(SAM)的“功能接口”,然后编译器生成一个实现。有一些优化,但是基本上是您在Java 7-中所做的。它的运行情况还不错,但是有很多尴尬的情况,因为函数没有完整的一流对象。

科特林,另一方面,确实具有正确的功能类型。这功能更强大,更灵活,但与Java的处理方式不符。

Kotlin编译器具有一些特殊情况,可以将lambda自动转换为Java SAM接口的实现。 (不过,在实现Kotlin接口时这并不适用,这会引起一些混乱。)

在将SAM实现lambda直接传递给方法的情况下,编译器可以推断其类型。 (就像@Slaw的第二个示例一样。)

但是在其他情况下,您需要在大括号之前指定接口名称。 (就像@Slaw的第一个示例一样。)

答案 1 :(得分:3)

由于ArgumentMatcher是Java功能接口,因此您需要使用:

fun customArgumentMatcher(size: Int): ArgumentMatcher<List<Person>> {
    return ArgumentMatcher { argument -> argument.size == size }
}

请参阅Kotlin参考资料的SAM Conversions部分。


您还可以使用:

fun customArgumentMatcher(size: Int) = ArgumentMatcher<List<Person>> { it.size == size }

请参阅gidds' answer,以了解为什么需要上述语法的一些背景。