类型化的Scala对象如何丢失其类型?

类型化的Scala对象如何丢失其类型?,scala,Scala,在下面的代码段中,entities是一个Map[String,Seq[String]]对象,我从其他代码段接收到它。目标是将实体对象映射到两列Spark数据帧中;但是,在我到达那里之前,我发现了一些非常不寻常的结果 val data: Map[String, Seq[String]] = Map("idtag" -> Seq("things", "associated", "with", "id")) println(data) println(data.toSeq) data.toSe

在下面的代码段中,
entities
是一个
Map[String,Seq[String]]
对象,我从其他代码段接收到它。目标是将实体对象映射到两列Spark数据帧中;但是,在我到达那里之前,我发现了一些非常不寻常的结果

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)
我硬编码的
数据
对象按预期运行。实体映射上的
.toSeq
函数生成元组的
Seq
(作为ArrayBuffer实现);这些元组可以通过映射进行处理

但是使用
实体
对象,您可以看到,当我使用
.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]]
复制这种奇怪的行为,正如您在这段代码中看到的那样。有人能解释这种行为及其发生的原因吗?

问题似乎是
实体。toSeq
在返回的数据类型上撒谎,所以我会查看“其他代码”并检查它是否做了正确的事情

具体来说,它声明返回
Seq[(String,Seq[String])]
,编译器相信它。但是
getClass
显示元组中的第二个对象实际上是
java.lang.String
而不是
Seq[String]

如果这是正确的,
match
语句将使用
unapply
提取值,然后在尝试将
名称
转换为所述类型时出错


我注意到该字符串似乎是一个包含在
[
]
中的字符串列表,因此似乎任何创建
实体的东西都无法将其解析为
序列
,而是声称它成功了。

什么是
实体
???您将其声明为
Seq[(String,Seq[String])]
,但显然不是这样。编译错误是预期的:您将其声明为
Seq
,然后尝试以
字符串的形式访问@Dima Entities不是我创建的。它的类型在第一句中给出。注意我通过
.toSeq
命令转换它的位置,以及分配给结果
val eSeq
的类型。编译错误当然是预期的,但第一个异常不是。请仔细阅读问题。我注意到
println(data.toSeq.head)
的输出和
println(eSeq.head)
的输出看起来不像是相关的数据格式。
[
]
从哪里来?一个在数据中有引号,
,但另一个没有。
实体
看起来或行为不像Scala创建的
映射[String,Seq[String]]
@jwvh我从另一个Scala软件中获得了
实体
;但我相信它的大部分起源是Java。我假设它是一个Java数组,但这似乎不正确。你已经触及了问题的核心,我不明白发生了什么。我为
eSeq
添加了一个特定类型,但这似乎没有帮助@问题是“第一句中给出的类型”是错误的。这就是为什么你会得到例外。我读得很透彻。请不要告诉我该怎么做。