Scala 2.11编译Spark 2.2.1代码报类型不匹配错误,2.12正常
解决Scala 2.11下Spark 2.2.1的JavaRDD.map()编译类型不匹配问题
这个问题的核心原因是Scala 2.11和2.12在Java单抽象方法(SAM)接口适配上的差异:
- Scala 2.12引入了SAM转换特性,允许将Scala函数字面量自动转换为Java的单抽象方法接口(比如Spark的
org.apache.spark.api.java.function.Function)。 - 但Scala 2.11并不支持这个自动转换,所以当你调用
toJavaRDD().map()时,传入的Scala函数无法被识别为Java的Function接口实例,导致编译报错。
解决方案一:显式实现Java Function接口
直接用Scala语法创建Java Function的匿名内部类,替代Scala函数字面量:
r_log_o.toJavaRDD.cache().map( new org.apache.spark.api.java.function.Function[Row, Timestamp] { override def call(x: Row): Timestamp = x(4).asInstanceOf[Timestamp] } ).reduce(minTs(_, _))
解决方案二:使用Scala原生RDD(更推荐)
既然你是用Scala写代码,完全没必要转成JavaRDD,直接使用Spark的Scala RDD API,这样可以直接用Scala函数,避免Java/Scala API的适配问题:
// 去掉toJavaRDD,直接用rdd方法获取Scala RDD r_log_o.rdd.cache().map(x => x(4).asInstanceOf[Timestamp]).reduce(minTs)
小优化:简化minTs方法
可以把你的minTs方法改成更符合Scala风格的写法:
def minTs(x: Timestamp, y: Timestamp): Timestamp = if (x.compareTo(y) < 0) x else y
这样修改后,在Scala 2.11环境下就能正常编译了。
内容的提问来源于stack exchange,提问作者giusy
相关产品推荐
相关产品推荐

