scala - 在 Scala 中的 map 上使用收集

标签 scala compiler-construction jvm scala-collections type-erasure

我最近偶然发现了这个 post ,它“介绍”了 collect Scala 集合的方法。用法很简单:

scala> val ints = List(1, "2", 3) collect { case i: Int => i }
ints: List[Int] = List(1, 3)

现在 map 基本上是键值对列表,在 Scala 中由元组表示。所以你可能想尝试这样的事情:
scala> val pairs = Map(1 -> "I", "II" -> 2)
pairs: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)

scala> val intsToStrings = pairs collect { case pair: (Int, String) => pair }

由于JVM的类型删除模型,编译器当然会提示,所以我们尝试的第一件事是使用存在类型:
scala> val intsToStrings = pairs collect { case pair: (_, _) => pair }
intsToString: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)

尽管代码通过了编译器,并且结果是“正确的”(我们想要对 => 我们得到对)我们仍然没有得到我们真正想要的。第二次尝试如下所示:
scala> val intsToStrings = pairs collect {
     |    case pair: (_, _) if pair._1.isInstanceOf[Int] && pair._2.isInstanceOf[String] => pair
     | }
intsToStrings: scala.collection.immutable.Map[Any,Any] = Map(1 -> I)

好的,我们快到了:
scala> val realIntsToRealStrings = intsToStrings map {
     |    pair => (pair._1.asInstanceOf[Int], pair._2.asInstanceOf[String])
     | }
realIntsToRealStrings: scala.collection.immutable.Map[Int,String] = Map(1 -> I)

我们做到了,但不仅仅是从 (Any,Any) 转换至 (Int,String)我们实际上复制了每一对,从而创建了一个新对。

现在是问题部分。正如我提到的“编译器当然会提示......”我听起来好像我真的知道我在说什么。我不!我只知道 Java 从一开始就没有泛型。在某些时候,泛型进入了 Java,但没有进入 JVM。因此编译器会检查所有类型,但是一旦代码运行,JVM 就不会关心参数类型。它只看到它是一个 MapList但并不是说它是 Map[String, Int]List[Int] .

所以这是我的问题。

通过所有的检查、转换和映射,我们设法转移了一个 Map[Any,Any]Map[String,Int] .有没有更好的方法来做到这一点?我的意思是类型在那里,JVM 只是没有看到它们(就我而言)......

最佳答案

pairs collect { case p @ (_: Int, _: String) => p.asInstanceOf[(Int, String)] }

或更简洁,但有一些开销,我认为
pairs collect { case (x: Int, y: String) => (x, y) }

关于scala - 在 Scala 中的 map 上使用收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6640927/

相关文章:

c# - Scala 最短相当于 c# LINQ

scala - 使用 FileStream 读取文件,会阻塞吗?

java - Java 7 中的编译器更改

内存中的Java原始数组布局

java - 当我运行我的程序时,我时不时会收到随机错误

java - 如何阅读 jvm 崩溃报告?报告的原因可能是什么

伴随对象中的Scala隐式Numeric [T]

Scaladoc [用例]

gcc - yacc 中的 %left 和 %right

c++ - 带有输入流的在线 C++ 编译器?