I need to pass a java.util.function.Predicate
to a Java function. How can I implement it as Lambda in Kotlin?
The Java-Function I need to call:
public void foo(Predicate<String> p)
Java Lambda implemenation ✔ :
foo(text-> true)
Kotlin Lambda implemenation ❌:
foo{text:String -> true}
^^^^^^^^^^^^
Type mismatch.
Required: Predicate<String>
Found: (String) → Boolean
Kotlin-Version 1.2.21
Since Kotlin 1.4
foo({text -> true })
or
foo {text -> true}
Before Kotlin 1.4
These variants work:
foo(Predicate {text -> true })
foo(Predicate {true})
foo({true }as Predicate<String>)
It works fine, here is a test that compiles with a Java List
and the filter
method that takes a Predicate
as parameter:
val test = Arrays.asList("Hello", "Bye", "World!")
println(test)
println(test.filter { it.startsWith("W") })
Is the last sample code ( foo{text:String -> true}
) your code that does not compile?
Between the braces, your are supposed to pass the implementation of the lambda, not the type/interface of it. This part is inferred for you!
As of Kotlin 1.4, there is support for Single Abstract Method (SAM) conversion for Java interfaces: https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
From the example in the question, the following works now:
foo { text -> true }
If in case want to declare as a property:
private val normal = Predicate<Int> { true }
private val even = Predicate<Int> { it % 2 == 0 }
private val odd = even.negate()
fun main() {
println("Normal count ${get(normal)}")
println("Even count ${get(even)}")
println("Odd count ${get(odd)}")
}
fun get(predicate: Predicate<Int>): Int {
val filter = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).filter { predicate.test(it)}
println(filter)
val map = filter.map { it * 2 }
println(map)
return map.sum()
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.