scala集合泛型数据类型转换成java集合遇到的问题

本文记录了线上遇到的Scala的Map集合转Java的Map集合时类型转换异常问题。先介绍了Scala与Java集合相互转换的常用工具包及方法,定位错误是Scala集合泛型中Long转Java集合时类型不匹配,最终通过将Scala集合泛型类型设为Java数据类型解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

今天在线上遇到一个很棘手的scala的Map集合转换为java的Map集合中类型转换异常的问题,百度上并没有找到相关解决方案。这儿特地记录一下这个问题。在叙述这个问题之前觉得有必要在记录一下常用的scala和java转换的知识。熟悉scala开发的人对scala.collection.JavaConversions._scala.collection.JavaConverters._肯定不陌生,这两个工具包封装了隐式java和scala集合相互转换的API。

scala与java集合相互转换

使用JavaConversionsJavaConverters都可以进行转换,需要注意的是:下面演示的无论是java还是scala相关的集合对象,其泛型参数类型都是scala的基本数据类型,这一点非常重要!

  • JavaConverters完成List集合转换
import scala.collection.JavaConverters._
// 创建泛型为Int类型的scala List集合
val scalaList:List[Int]= List(1,2,3,4,5)
// 将scala List集合转java List集合
val javaList:java.util.List[Int] = scalaList.asJava

// 创建java List集合
val List = new util.ArrayList[Int]()
// 将java List集合转为scala List集合
val scalalist2 = list.asScala
  • JavaConverters完成Map集合转换
import scala.collection.JavaConverters._
// 创建scala的map集合
val map: Map[String, Int] = Map("8" -> 15, "4" -> 3000)
// 将scala的map集合转为java map集合
val javaMap = map.asJava

// 创建java的Map集合
val javaMap1 = new util.HashMap[String,Int]()
// 将java的Map集合转为scala的Map
val scalaMap = javaMap1.asScala

这里特地说一下:JavaConversions转换都是隐式的。

  • JavaConversions 完成List集合转换
import scala.collection.JavaConversions._
// 创建泛型为Int类型的scala List集合
val scalaList: List[Int] = List(1, 2, 3, 4, 5)
// 将scala List集合转java List集合
val javaList =seqAsJavaList(scalaList)

// 创建java List集合
val list = new util.ArrayList[Int]()
// 将java List集合转为scala List集合
val scalalist2 = list.toList

  • JavaConversions 完成Map集合转换
import scala.collection.JavaConversions._
// 创建java的Map集合
val javaMap = new util.HashMap[String,Int]()
// 将java的Map集合转为scala的Map
val scalaMap = javaMap.toMap

// 创建scala的map集合
val map: Map[String, Int] = Map("8" -> 15, "4" -> 3000)
// 将scala的map集合转换成java的map集合
val javaMap = mapAsJavaMap(map)

以上两个包下还提供了其他scala和java数据类型转换如set集合等,具体可以参考官方文档,这里就不在介绍了。

错误定位

上面介绍java和scala集合转换的示例,这次错误主要是scala的集合泛型中Long数据类型转换java的集合中直接转换成java的Integer,而不是我们想要的java的Long类型。

项目中参数的返回值如下图所示:
在这里插入图片描述
可以很清晰看到返回的参数是Map[String, Long],而这个返回值作为了项目中的一个方法的入参参数如下图所示:
在这里插入图片描述
这里的Map对象是java.util.Map那个对象,所以这儿自然就想到将scala的Map[String, Long]转换java对应的数据集合类型就好。但是编译报了类型不匹配的的错误:
在这里插入图片描述
现在才发现上面转换后的java的Map集合泛型类型是scala的数据类型,并不是原生的java数据类型。所以这儿将上面的集合做一次类型转换,就像下面这样:

mapAsJavaMap(prize).asInstanceOf[java.util.Map[java.lang.String,java.lang.Long]]

这么写好了大功告成,but当测试的时候,发现执行报了以下的错误:
在这里插入图片描述
这里报了类型转换的异常,从Map[String, Long]java.util.Map[java.lang.String,java.lang.Long]转换过程应该是这样的过程:scala的Long类型转换成了java的Integer类型,然后在将这个Integer类型转成java的Long类型

解决

查阅百度相关博客,大多数都是scala和java集合转换的相关博客,并没有集合转换异常的收录。最后抱着试一试的态度将最开始的findMap4Prize这个方法的返回值修改为:Map[String, java.lang.Long]发现问题竟然解决了。原生的scala的Long类型竟然不可以直接转换成java的Long类型数据,猜测应该是scala语言的一个bug(本人使用scala的版本号是2.11.8)。

若类似scala集合转化java集合出现的cast exception都可以直接将scala集合的泛型类型设置为java的数据类型即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值