如何将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的属性类型。