尝试从RDD返回Map [(String,String),(Double,Double)]时无法将java.lang.String强制转换为java.lang.Double错误

时间:2018-06-19 16:22:04

标签: scala apache-spark

我正在尝试使用|分隔符作为RDD读取.txt文件,并尝试返回Map[(String, String),(Double, Double)],但是我遇到了CastException

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double

输入数据如下

string1|string2|100.00|200.00
string1|string2|34.98|0.989

这就是我以rdd格式读取文件并进行解析的方式

val mydata = sc
  .textFile("file")
  .map(line => line.split("|"))
  .map(row =>
    ((row(0), row(1)),
     (row(2).asInstanceOf[Double], row(3).asInstanceOf[Double])))
  .collect
  .toMap

如何解决此问题

预期o / p:

Map[(String, String),(Double, Double)] = Map((string1,string2) -> (100.0,200.0), (string1,string2) -> (34.98,0.989))

1 个答案:

答案 0 :(得分:2)

为了安全起见,您可以使用trim功能,也可以使用collectAsMap

val mydata = sc
  .textFile("file")
  .map(line => line.split("\\|"))
  .map(row =>
    ((row(0), row(1)),
      (row(2).trim.asInstanceOf[Double], row(3).trim.asInstanceOf[Double])))
  .collectAsMap()

为了更加安全,您可以使用Try/getOrElse

val mydata = sc
  .textFile("file")
  .map(line => line.split("\\|"))
  .map(row =>
    ((row(0), row(1)),
      (Try(row(2).trim.asInstanceOf[Double]).getOrElse(0.0), Try(row(3).trim.asInstanceOf[Double]).getOrElse(0.0))))
  .collectAsMap()

此外,您可以使用toDouble代替asInstanceOf[Double]

val mydata = sc
  .textFile("file")
  .map(line => line.split("\\|"))
  .map(row =>
    ((row(0), row(1)), 
      (Try(row(2).trim.toDouble).getOrElse(0.0), Try(row(3).trim.toDouble).getOrElse(0.0)))
  )
  .collectAsMap().foreach(println)