我有一个Java示例,其中方法实现为
COUNTA(A1:A10)
IntelliJ将其自动翻译为Kotlin是
=FILTER(A1:A10, NOT(COUNTIF(QUERY({B1:B8;
TRANSPOSE(SPLIT(REPT("♂♀", COUNTA(A1:A10)-COUNTA(B1:B8)+1), "♀"))},
"limit "&COUNTA(A1:A10), 0), A1:A10)))
(我明确了项目类型,并将其更改为0.0)
我仍然看到Java的Function和Kotlin本机lambda存在兼容性问题,但我并不是最熟悉这些问题。错误是:
问题是:是否可以在Kotlin中覆盖此示例上的外部Java库的Fitness()方法,如果可以,如何覆盖?
答案 0 :(得分:3)
问题:
您返回的是(Kotlin)lambda ISeq<Knapsack.Item> -> Double
。但这不是您想要的。您要返回Java Function<ISeq<Knapsack.Item>, Double>
。
解决方案:
您可以使用SAM Conversion创建一个Function
。
就像Java 8一样,Kotlin支持SAM转换。这意味着 Kotlin函数文字可以自动转换为 Java接口的单个非默认方法的实现, 只要接口方法的参数类型与 Kotlin函数的参数类型。
我创建了一个最小的示例来说明这一点。考虑您有一个这样的Java类:
public class Foo {
public Function<String, Integer> getFunction() {
return item -> Integer.valueOf(item);
}
}
如果您想在Kotlin中覆盖getFunction
,您可以这样做:
class Bar: Foo() {
override fun getFunction(): Function<String, Int> {
return Function {
it.toInt()
}
}
}
答案 1 :(得分:1)
当返回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有自己的同名类