如何将java.util.List转换为Scala的List?
2021-12-08 20:02:38.0
因为Scala API和Java API可以互操作,所以在使用Scala API开发Spark应用时,我们经常会遇到这样的场景:调用Java的API库/包,返回的是java.util.List类型,但是我们需要的是Scala的List类型(scala.collection.immutable.List)。
换句话说,如何把java.util.List类型转换为Scala的List类型?
首先,请看下面这个示例场景。在这个场景中,我们使用结巴分词包对一个字符串进行分词(你可以理解为这个字符串是DataFrame中的一个属性):
import com.huaban.analysis.jieba.JiebaSegmenter
object Test {
def main(args: Array[String]): Unit = {
val feature = "正品相宜本草黑茶男士清爽骄阳防晒露护理防晒霜控油保湿护肤品"
// 默认
val words: java.util.List[String] = new JiebaSegmenter().sentenceProcess(feature)
// 输出
words.forEach(println)
}
}
在上面的代码中,我们对feature字符串变量进行分词,得到的结果是java.util.List
执行以上代码,可以看到输出如下这样的分词结果:
正品 相宜 本草 黑茶 男士 清爽 骄阳 防晒露 护理 防晒霜 控油 保湿 护肤品
但是这里存在着这样一个问题:Spark DataFrame并不支持java.util.List
- 将返回的java.util.List
转换为String类型(调用toString()方法); - 将返回的java.util.List
转换为Scala的List[String]类型。
第一种方法我们在此不再赘述。我们只研究第二种方式,如何将java.util.List
可以简单地使用Scala的scala.collection.JavaConverters类来进行转换,如下所示:
import com.huaban.analysis.jieba.JiebaSegmenter
import scala.collection.JavaConverters._
object Test {
def main(args: Array[String]): Unit = {
val feature = "正品相宜本草黑茶男士清爽骄阳防晒露护理防晒霜控油保湿护肤品"
// 从java.util.List 转换为 scala.collection.immutable.List
// val words: scala.collection.immutable.List[String] = new JiebaSegmenter().sentenceProcess(feature).asScala.toList
// 可简化如下
val words = new JiebaSegmenter().sentenceProcess(feature).asScala.toList
words.foreach(println)
}
}
需要注意的是,从Scala 2.13开始, scala.collection.JavaConverters包被标记为弃用,请使用scala.jdk.CollectionConverters包。例如:
import com.huaban.analysis.jieba.JiebaSegmenter
import scala.jdk.CollectionConverters._ // 注意这里的变化
object Test {
def main(args: Array[String]): Unit = {
val feature = "正品相宜本草黑茶男士清爽骄阳防晒露护理防晒霜控油保湿护肤品"
// 从java.util.List 转换为 scala.collection.immutable.List
val words = new JiebaSegmenter().sentenceProcess(feature).asScala.toList
words.foreach(println)
}
}
这时返回的words就是一个Scala List,可直接作为DataFrame的属性类型。