Java8高阶函数和Kotlin Lambdas互操作性
我有一个Java示例,其中一个方法实现为Java8高阶函数和Kotlin Lambdas互操作性,kotlin,functional-interface,Kotlin,Functional Interface,我有一个Java示例,其中一个方法实现为 @Override public Function<ISeq<Item>, Double> fitness() { return items -> { final Item sum = items.stream().collect(Item.toSum()); return sum._size <= _knapsackSize ? sum._value : 0; }; }
@Override
public Function<ISeq<Item>, Double> fitness() {
return items -> {
final Item sum = items.stream().collect(Item.toSum());
return sum._size <= _knapsackSize ? sum._value : 0;
};
}
IntelliJ自动将其翻译成Kotlin是
override fun fitness(): Function<ISeq<Item>, Double> {
return { items:ISeq<Item> ->
val sum = items.stream().collect(Item.toSum())
if (sum.size <= _knapsackSize) sum.value else 0.0
}
}
我将项目类型显式化,并将其更改为返回0.0
尽管如此,我仍然看到Java函数和Kotlin native lambdas之间存在兼容性问题,但我对这些并不太熟悉。错误是:
问题是:在本例中是否可以在Kotlin中重写外部Java库的适应度方法?如果可以,如何重写?当将lambda作为Java的函数接口返回时,必须使用显式SAM构造函数:
override fun fitness(): Function<ISeq<Item>, Double> {
return Function { items:ISeq<Item> ->
val sum = items.stream().collect(Item.toSum())
if (sum.size <= _knapsackSize) sum.value else 0.0
}
}
另外,不要忘记导入java.util.function.function,因为Kotlin有自己的同名类问题:
您返回的是Kotlin lambda ISeq->Double。但这不是你想要的。您希望返回一个Java函数
解决方案:
可以使用创建函数
与Java8一样,Kotlin支持SAM转换。这意味着
Kotlin函数文本可以自动转换为
使用单个非默认方法实现Java接口,
只要接口方法的参数类型与
Kotlin函数的参数类型
我创建了一个简单的示例来演示这一点。假设你有这样的java类:
public class Foo {
public Function<String, Integer> getFunction() {
return item -> Integer.valueOf(item);
}
}
class Bar: Foo() {
override fun getFunction(): Function<String, Int> {
return Function {
it.toInt()
}
}
}