如何在 Scala 中使用 Java lambda
How to use Java lambdas in Scala
我有以下代码:
source
.mapValues(value -> value + " Stream it!!!")
.print(Printed.toSysOut());
如您所见,mapValues
需要一个 lambda 表达式。
现在,我正在使用 Java 库,但该应用程序是用 Scala 编写的。如何将 Scala lambda 传递给 Java 代码?
我尝试了以下方法:
source
.mapValues(value => value + "hello")
.print(Printed.toSysOut)
但是编译器报错:
[error] (x: org.apache.kafka.streams.kstream.Printed[String,?0(in value x)])Unit <and>
[error] (x: org.apache.kafka.streams.kstream.KeyValueMapper[_ >: String, _ >: ?0(in value x), String])Unit <and>
[error] (x: 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
错误消息列出了print
支持的参数类型。其中之一是:
org.apache.kafka.streams.kstream.Printed[String,?0(in value x)]
从错误消息中可以看出,您正在向 Printed.toSysOut
提供以下类型:
org.apache.kafka.streams.kstream.Printed[Nothing,Nothing]
According to the Kafka 1 javadoc(Printed
在 Kafka 1.1 中不存在),toSysOut
定义为:
public static <K,V> Printed<K,V> toSysOut()
所以答案问题是 Scala 正在推断 K
和 V
类型为 Nothing
。您需要明确提供类型。
以下可能有效:
source
.mapValues[String](value -> value + " Stream it!!!")
.print(Printed.toSysOut[String,String])
这取决于您的 Scala 版本。
在 2.12 中,Scala 函数可以用在需要 Java 函数的地方,反之亦然。
App1.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"))
}
}
在 2.11 中你可以使用 scala-java8-compat
libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
App1.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"))
}
}
或者在 Scala 的 2.11 中,您可以 define implicit converters 在 java.util.function.Function
和 scala.Function1
之间。
所以如果你使用 2.11 试试
source
.mapValues((value => value + "hello").asJava)
.print(Printed.toSysOut)
或
source
.mapValues(((value: String) => value + "hello").asJava)
.print(Printed.toSysOut[String, String])
我有以下代码:
source
.mapValues(value -> value + " Stream it!!!")
.print(Printed.toSysOut());
如您所见,mapValues
需要一个 lambda 表达式。
现在,我正在使用 Java 库,但该应用程序是用 Scala 编写的。如何将 Scala lambda 传递给 Java 代码?
我尝试了以下方法:
source
.mapValues(value => value + "hello")
.print(Printed.toSysOut)
但是编译器报错:
[error] (x: org.apache.kafka.streams.kstream.Printed[String,?0(in value x)])Unit <and>
[error] (x: org.apache.kafka.streams.kstream.KeyValueMapper[_ >: String, _ >: ?0(in value x), String])Unit <and>
[error] (x: 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
错误消息列出了print
支持的参数类型。其中之一是:
org.apache.kafka.streams.kstream.Printed[String,?0(in value x)]
从错误消息中可以看出,您正在向 Printed.toSysOut
提供以下类型:
org.apache.kafka.streams.kstream.Printed[Nothing,Nothing]
According to the Kafka 1 javadoc(Printed
在 Kafka 1.1 中不存在),toSysOut
定义为:
public static <K,V> Printed<K,V> toSysOut()
所以答案问题是 Scala 正在推断 K
和 V
类型为 Nothing
。您需要明确提供类型。
以下可能有效:
source
.mapValues[String](value -> value + " Stream it!!!")
.print(Printed.toSysOut[String,String])
这取决于您的 Scala 版本。
在 2.12 中,Scala 函数可以用在需要 Java 函数的地方,反之亦然。
App1.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"))
}
}
在 2.11 中你可以使用 scala-java8-compat
libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0"
App1.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"))
}
}
或者在 Scala 的 2.11 中,您可以 define implicit converters 在 java.util.function.Function
和 scala.Function1
之间。
所以如果你使用 2.11 试试
source
.mapValues((value => value + "hello").asJava)
.print(Printed.toSysOut)
或
source
.mapValues(((value: String) => value + "hello").asJava)
.print(Printed.toSysOut[String, String])