Scala 获取 java.lang.ClassCastException:java.math.BigDecimal 无法转换为 java.lang.Double
Scala Getting java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double
我的查询是这样的
val demo = spark.sql(s"select PERCENTILE_APPROX(weight,array(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)) from db.demo_input_data")
scala> demo.first.getList(0)
res0: java.util.List[Nothing] = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
我的最终目标是通过以下命令获取数据
scala> val BenchmarkPercentile = ":10"
scala> demo.first.getList(0).map((x: Double) => x + BenchmarkPercentile)
当我 运行 这个命令时我得到以下错误
java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double
at scala.runtime.BoxesRunTime.unboxToDouble(BoxesRunTime.java:114)
at $anonfun.apply(<console>:31)
at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:234)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
... 51 elided
另一方面,如果我的数据集不同,如果我得到以下数据,命令工作正常
scala> val demo1 = spark.sql(s"select PERCENTILE_APPROX(weight,array(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)) from db.demo_input_data1")
scala> demo1.first.getList(0)
res1: java.util.List[Nothing] = [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
请帮我理解为什么会这样。
注意:- 在 运行 上面的代码
之前,我还发出了以下命令
scala> import scala.collection.JavaConversions._
这里的问题是您需要处理正确的类型。我的意思是,您的 sql 查询创建了一个具有特定模式的数据框。在您的例子中,您创建了 demo1 数据框并获得了第一行。然后,第一列为 java.util.List,因此您将数据框带到 jvm(Scala 类型)世界。因为 Dataframe api 是无类型的,不像 Dataset api,你必须手动处理类型不匹配:
demo.first.getList(0).map((x: BigDecimal) => x + BenchmarkPercentile)
查看有关类型的 Spar 文档:https://spark.apache.org/docs/latest/sql-ref-datatypes.html
我的查询是这样的
val demo = spark.sql(s"select PERCENTILE_APPROX(weight,array(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)) from db.demo_input_data")
scala> demo.first.getList(0)
res0: java.util.List[Nothing] = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
我的最终目标是通过以下命令获取数据
scala> val BenchmarkPercentile = ":10"
scala> demo.first.getList(0).map((x: Double) => x + BenchmarkPercentile)
当我 运行 这个命令时我得到以下错误
java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double
at scala.runtime.BoxesRunTime.unboxToDouble(BoxesRunTime.java:114)
at $anonfun.apply(<console>:31)
at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:234)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
... 51 elided
另一方面,如果我的数据集不同,如果我得到以下数据,命令工作正常
scala> val demo1 = spark.sql(s"select PERCENTILE_APPROX(weight,array(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)) from db.demo_input_data1")
scala> demo1.first.getList(0)
res1: java.util.List[Nothing] = [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
请帮我理解为什么会这样。
注意:- 在 运行 上面的代码
scala> import scala.collection.JavaConversions._
这里的问题是您需要处理正确的类型。我的意思是,您的 sql 查询创建了一个具有特定模式的数据框。在您的例子中,您创建了 demo1 数据框并获得了第一行。然后,第一列为 java.util.List,因此您将数据框带到 jvm(Scala 类型)世界。因为 Dataframe api 是无类型的,不像 Dataset api,你必须手动处理类型不匹配:
demo.first.getList(0).map((x: BigDecimal) => x + BenchmarkPercentile)
查看有关类型的 Spar 文档:https://spark.apache.org/docs/latest/sql-ref-datatypes.html