[英]How to use Java lambdas in Scala
I have the following code:我有以下代码:
source
.mapValues(value -> value + " Stream it!!!")
.print(Printed.toSysOut());
as you can see, mapValues
expects a lambda expression.如您所见,
mapValues
需要一个 lambda 表达式。
Now, I am using Java library but the application is written in Scala.现在,我正在使用 Java 库,但应用程序是用 Scala 编写的。 How to pass Scala lambda to Java code?
如何将 Scala lambda 传递给 Java 代码?
I tried the following:我尝试了以下方法:
source
.mapValues(value => value + "hello")
.print(Printed.toSysOut)
But the compiler complains:但是编译器抱怨:
[error] (x$1: org.apache.kafka.streams.kstream.Printed[String,?0(in value x$1)])Unit <and>
[error] (x$1: org.apache.kafka.streams.kstream.KeyValueMapper[_ >: String, _ >: ?0(in value x$1), String])Unit <and>
[error] (x$1: String)Unit
[error] cannot be applied to (org.apache.kafka.streams.kstream.Printed[Nothing,Nothing])
[error] .print(Printed.toSysOut)
[error] ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed Nov 19, 2017 7:53:44 PM
It depends on your version of Scala.这取决于您的 Scala 版本。
In 2.12 Scala functions can be used in places where Java functions are expected and vice versa.在 2.12 中,Scala 函数可用于需要 Java 函数的地方,反之亦然。
App1.java应用程序1.java
import java.util.function.Function;
public class App1 {
public static void method(Function<String, String> function) {
System.out.println(function.apply("a"));
}
public static void main(String[] args) {
App.method1((String s) -> s.toUpperCase());
}
}
App.scala应用程序
object App {
def main(args: Array[String]): Unit = {
App1.method((s: String) => s.toUpperCase)
}
def method1(function: String => String): Unit = {
println(function("xyz"))
}
}
In 2.11 you can use scala-java8-compat
在 2.11 你可以使用
scala-java8-compat
libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
App1.java应用程序1.java
import java.util.function.Function;
import static scala.compat.java8.JFunction.func;
public class App1 {
public static void method(Function<String, String> function) {
System.out.println(function.apply("a"));
}
public static void main(String[] args) {
App.method1(func((String s) -> s.toUpperCase()));
}
}
App.scala应用程序
import scala.compat.java8.FunctionConverters._
object App {
def main(args: Array[String]): Unit = {
App1.method(((s: String) => s.toUpperCase).asJava)
}
def method1(function: String => String): Unit = {
println(function("xyz"))
}
}
Alternatively in 2.11 in Scala you can define implicit converters between java.util.function.Function
and scala.Function1
.或者,在 Scala 的 2.11 中,您可以在
java.util.function.Function
和scala.Function1
之间 定义隐式转换器。
So if you use 2.11 try所以如果你使用 2.11 试试
source
.mapValues((value => value + "hello").asJava)
.print(Printed.toSysOut)
or或者
source
.mapValues(((value: String) => value + "hello").asJava)
.print(Printed.toSysOut[String, String])
The error message lists the types of arguments that print
supports.错误消息列出了
print
支持的参数类型。 One of them is:其中之一是:
org.apache.kafka.streams.kstream.Printed[String,?0(in value x$1)]
From the error message you can see that you're providing Printed.toSysOut
with a type of:从错误消息中,您可以看到您提供的
Printed.toSysOut
类型为:
org.apache.kafka.streams.kstream.Printed[Nothing,Nothing]
According to the Kafka 1 javadoc ( Printed
was not present in Kafka 1.1), toSysOut
is defined as: 根据 Kafka 1 javadoc (在 Kafka 1.1 中不存在
Printed
), toSysOut
定义为:
public static <K,V> Printed<K,V> toSysOut()
So the answer problem is that Scala is inferring K
and V
with types of Nothing
.所以答案问题是 Scala 推断
K
和V
类型为Nothing
。 You need to provide the types explicitly.您需要明确提供类型。
The following will probably work:以下可能会起作用:
source
.mapValues[String](value -> value + " Stream it!!!")
.print(Printed.toSysOut[String,String])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.