如何在 Java 中使用 Scala 隐式 class
How to use Scala implicit class in Java
我有一个来自 RecordService API 的 Scala 隐式 class,我想在 Java 文件中使用它。
package object spark {
implicit class RecordServiceContext(ctx: SparkContext) {
def recordServiceTextFile(path: String) : RDD[String] = {
new RecordServiceRDD(ctx).setPath(path)
.map(v => v(0).asInstanceOf[Text].toString)
}
}
}
现在我正在尝试使用下面的导入将其导入到 Java 文件中。
import com.cloudera.recordservice.spark.*;
但是我无法使用 sparkContext 中的 recordServiceTextFile("path")。
在 Scala 中,导入和它的工作方式略有不同。
SparkContext ctx = ...
RecordServiceContext rsct = new RecordServiceContext(ctx)
recordServiceTextFile("/your_path")
这应该可以做到。
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
虽然我更改了签名。
我的 Scala class 看起来像这样,
object spark {
implicit class RecordServiceContext(ctx: String) {
def recordServiceTextFile(path: String) : String = {
"test"
}
}
}
我的javaclass是这样的,
public class TestScalaCall {
public static void main(String args[]){
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
}
}
编辑---
因此,快速查看 Scala 更改请求向我们展示了 this。
他们实际上正在努力使在 package object
下定义的 class 的行为方式与在常规 package
中定义它的方式相同。但这是针对尚未发布的 2.12
.
因此他们给出的建议是只保留绝对必要的 classes/objects,不需要在包对象内部进行任何外部交互。否则将它们放在常规包装下。
所以现在你不需要使用 package object
结构。
另外,值得深思的一点"Does it really make sense to define something that is accessible on the outside inside a package object ? "
一个package object spark
在包spark
中被编译成一个classpackage
。隐式 class RecordServiceContext
将在 package
和 class package$RecordServiceContext
中编译为静态方法 RecordServiceContext
(这是 scala 的隐式定义)。 =20=]
所以下面的代码应该可以做到:
import com.cloudera.recordservice.spark.*;
//some code
RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile);
//some code
但是package
可能是一个保留关键字,据我所知Java没有办法转义它们。因此,您必须进行一些反思才能调用 RecordServiceContext
方法。
这里是包对象
中隐式class的简单定义
package object spark {
implicit class Ext(param: Int) {
def a = param + 1
}
}
这是 java
中的使用方法
public class Test {
public static void main(String[] args) {
spark.package$.MODULE$.Ext(123).a();
}
}
所以你基本上可以使用 RecordServiceContext
作为包装你的 SparkContext
的方法并添加一个你可以调用的额外方法。这是对隐式 classes.
的优化
那就是这样的:
SparkContext c = ???
RDD<String> rdd = com.cloudera.recordservice.spark.package$.MODULE$.RecordServiceContext(c)
.recordServiceTextFile("asdf");
我有一个来自 RecordService API 的 Scala 隐式 class,我想在 Java 文件中使用它。
package object spark {
implicit class RecordServiceContext(ctx: SparkContext) {
def recordServiceTextFile(path: String) : RDD[String] = {
new RecordServiceRDD(ctx).setPath(path)
.map(v => v(0).asInstanceOf[Text].toString)
}
}
}
现在我正在尝试使用下面的导入将其导入到 Java 文件中。
import com.cloudera.recordservice.spark.*;
但是我无法使用 sparkContext 中的 recordServiceTextFile("path")。
在 Scala 中,导入和它的工作方式略有不同。
SparkContext ctx = ...
RecordServiceContext rsct = new RecordServiceContext(ctx)
recordServiceTextFile("/your_path")
这应该可以做到。
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
虽然我更改了签名。
我的 Scala class 看起来像这样,
object spark {
implicit class RecordServiceContext(ctx: String) {
def recordServiceTextFile(path: String) : String = {
"test"
}
}
}
我的javaclass是这样的,
public class TestScalaCall {
public static void main(String args[]){
String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf");
}
}
编辑---
因此,快速查看 Scala 更改请求向我们展示了 this。
他们实际上正在努力使在 package object
下定义的 class 的行为方式与在常规 package
中定义它的方式相同。但这是针对尚未发布的 2.12
.
因此他们给出的建议是只保留绝对必要的 classes/objects,不需要在包对象内部进行任何外部交互。否则将它们放在常规包装下。
所以现在你不需要使用 package object
结构。
另外,值得深思的一点"Does it really make sense to define something that is accessible on the outside inside a package object ? "
一个package object spark
在包spark
中被编译成一个classpackage
。隐式 class RecordServiceContext
将在 package
和 class package$RecordServiceContext
中编译为静态方法 RecordServiceContext
(这是 scala 的隐式定义)。 =20=]
所以下面的代码应该可以做到:
import com.cloudera.recordservice.spark.*;
//some code
RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile);
//some code
但是package
可能是一个保留关键字,据我所知Java没有办法转义它们。因此,您必须进行一些反思才能调用 RecordServiceContext
方法。
这里是包对象
中隐式class的简单定义package object spark {
implicit class Ext(param: Int) {
def a = param + 1
}
}
这是 java
中的使用方法public class Test {
public static void main(String[] args) {
spark.package$.MODULE$.Ext(123).a();
}
}
所以你基本上可以使用 RecordServiceContext
作为包装你的 SparkContext
的方法并添加一个你可以调用的额外方法。这是对隐式 classes.
那就是这样的:
SparkContext c = ???
RDD<String> rdd = com.cloudera.recordservice.spark.package$.MODULE$.RecordServiceContext(c)
.recordServiceTextFile("asdf");