Spark升级后Java转Scala Map报错,求正确实现方案
解决Spark 3.4.1(Scala 2.13)中Java Map转Scala Immutable Map的问题
问题根源
Scala 2.13对集合API做了两处关键调整:
- 移除了基于
CanBuildFrom的隐式参数依赖,原toMap的调用方式不再适用 - 废弃并移除了
JavaConversions类,统一使用JavaConverters进行Java/Scala集合互转
正确实现方式
方式一:基于JavaConverters的最简转换
直接将Java Map转为Scala可变Map,再调用无参toMap得到不可变Map:
import scala.collection.JavaConverters; import scala.collection.immutable.Map; private static <A, B> Map<A, B> toScalaMap(java.util.Map<A, B> javaMap) { return JavaConverters.mapAsScalaMapConverter(javaMap) .asScala() .toMap(); }
方式二:通过Tuple序列构建
如果需要手动处理键值对转换,使用JavaConverters替代废弃的JavaConversions:
import scala.Tuple2; import scala.collection.JavaConverters; import scala.collection.immutable.Map; import java.util.stream.Collectors; private static <A, B> Map<A, B> toScalaMap(java.util.Map<A, B> javaMap) { // 将Java Map转成Scala Tuple2序列 var scalaTupleSeq = JavaConverters.collectionAsScalaIterableConverter( javaMap.entrySet().stream() .map(entry -> Tuple2.apply(entry.getKey(), entry.getValue())) .collect(Collectors.toList()) ).asScala().toSeq(); // 用Scala Map伴生对象构建不可变Map return Map$.MODULE$.apply(scalaTupleSeq); }
方式三:直接用Map.from构建
更简洁的方式,利用Map.from接收Scala集合构建不可变Map:
import scala.collection.JavaConverters; import scala.collection.immutable.Map; private static <A, B> Map<A, B> toScalaMap(java.util.Map<A, B> javaMap) { return Map$.MODULE$.from( JavaConverters.mapAsScalaMapConverter(javaMap).asScala() ); }
错误原因说明
- 原代码1报错:Scala 2.13中
mutable.Map.toMap不再需要传入Predef.$conforms()这类隐式参数,直接调用无参方法即可生成不可变Map - 原代码2报错:
JavaConversions在Scala 2.13中已被移除,必须使用JavaConverters中的转换器方法完成Java/Scala集合转换
业务场景适配
上述实现的toScalaMap函数可直接用于Spark from_csv API的参数传递,无需修改原有调用代码。
内容的提问来源于stack exchange,提问作者Joseph Hwang
相关产品推荐
相关产品推荐

