在下面的代码段中,entities
是我从其他代码段收到的Map[String, Seq[String]]
对象。目标是将实体对象映射到两列的Spark DataFrame中。但是,在到达那里之前,我发现了一些非常不寻常的结果。
val data: Map[String, Seq[String]] = Map("idtag" -> Seq("things", "associated", "with", "id"))
println(data)
println(data.toSeq)
data.toSeq.foreach{println}
data.toSeq.map{case(id: String, names: Seq[String]) => names}.foreach{println}
val eSeq: Seq[(String, Seq[String])] = entities.toSeq
println(eSeq.head)
println(eSeq.head.getClass)
println(eSeq.head._1.getClass)
println(eSeq.head._2.getClass)
eSeq.map{case(id: String, names: Seq[String]) => names}.foreach{println}
上面在控制台上的输出是:
Map(idtag -> List(things, associated, with, id))
ArrayBuffer((idtag,List(things, associated, with, id)))
(idtag,List(things, associated, with, id))
List(things, associated, with, id)
(0CY4NZ-E,["MEC", "Marriott-MEC", "Media IQ - Kimberly Clark c/o Mindshare", "Mindshare", "WPP", "WPP Plc", "Wavemaker Global", "Wavemaker Global Ltd"])
class scala.Tuple2
class java.lang.String
class java.lang.String
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to scala.collection.Seq
at package.EntityList$$anonfun$toStorage$4.apply(EntityList.scala:31)
我硬编码的data
对象按预期方式工作。实体图上的.toSeq
函数产生一个Seq
(实现为ArrayBuffer)元组;这些元组可以通过映射进行处理。
但是使用entities
对象,您可以看到,当我使用.head
获取第一个元素时,它是一个Tuple2[String, String]
。那怎么可能发生?元组的第二个元素如何变成字符串并引起异常?
如果最后一行更改为反映Tuple2[String, String]
,还会使我感到困惑:
eSeq.map{case(id: String, names: String) => names}.foreach{println}
然后我们得到一个编译错误:
/path/to/repo/src/main/scala/package/EntityList.scala:31: error: pattern type is incompatible with expected type;
found : String
required: Seq[String]
eSeq.map{case(id: String, names: String) => names}.foreach{println}
我无法用自己创建的Map[String, Seq[String]]
复制这种奇怪的行为,如您在此代码中所见。谁能解释这种行为及其原因?
答案 0 :(得分:2)
问题似乎是entities.toSeq
在关于返回的数据类型的谎言,所以我要看“其他代码”并检查它是否做对了。
具体来说,它声称返回Seq[(String, Seq[String])]
并且编译器相信它。但是getClass
表明元组中的第二个对象实际上是java.lang.String
而不是Seq[String]
。
如果这是正确的,则match
语句将使用unapply
提取值,然后在尝试将names
转换为指定的类型时出错。
我注意到,该字符串似乎是[
]
中包含的字符串的列表,因此,创建entities
的任何内容似乎都无法将其解析为{{ 1}},但声称它已经成功。