Reputation: 1119
I have a Java example where a method is implemented as
@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's automatic translation of it to Kotlin is
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
}
}
(I made the type of items explicit and changed return to 0.0)
Still I see that there are compatibility problems with Java's Function and Kotlin native lambdas, but I'm not that the most familiar with these. Error is:
Question is: is it possible to override in Kotlin the external Java library's fitness() method on this example and if so how ?
Upvotes: 2
Views: 842
Reputation: 29844
Problem:
You are returning a (Kotlin) lambda ISeq<Knapsack.Item> -> Double
. But this is not what you want. You want to return a Java Function<ISeq<Knapsack.Item>, Double>
.
Solution:
You can use a SAM Conversion to create a Function
.
Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.
I created a minimal example to demonstrate that. Consider you have a Java class like this:
public class Foo {
public Function<String, Integer> getFunction() {
return item -> Integer.valueOf(item);
}
}
If you want to override getFunction
in Kotlin you would do it like this:
class Bar: Foo() {
override fun getFunction(): Function<String, Int> {
return Function {
it.toInt()
}
}
}
Upvotes: 3
Reputation: 536
When returning lambda as Java's functional interface, you have to use explicit SAM constructor:
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
}
}
Also don't forget to import java.util.function.Function
since Kotlin has its own class of that name
Upvotes: 1