【问题标题】:TreeMap Keys and Iteration in ScalaScala 中的 TreeMap 键和迭代
【发布时间】:2016-09-12 06:13:47
【问题描述】:

我正在使用TreeMap,它在以下代码中的行为很奇怪。

代码如下:

import scala.collection.immutable.TreeMap
object TreeMapTest extends App{

  val mp = TreeMap((0,1) -> "a", (0,2) -> "b", (1,3) -> "c", (3,4) -> "f")
  mp.keys.foreach(println) //A
  println("****")
  mp.map(x => x._1).foreach(println) //B
}

如您所见,两条打印线(A 和 B)应该打印相同的内容,但结果如下:

(0,1)
(0,2)
(1,3)
(3,4)
****
(0,2)
(1,3)
(3,4)

为什么会发生这种情况?有趣的是,甚至 IDE 都认为可以互换使用这两者并建议替换。

【问题讨论】:

  • 我不认为keys 的顺序是问题所在。第二个示例中似乎缺少第一个键。
  • 啊,呃。谢谢。我认为这只是问题中的一个错误!

标签: scala collections treemap


【解决方案1】:

Scala 集合库通常会尝试返回与它开始时相同的集合,例如val seq: Seq[Int] = ...; seq.map(...) 将返回 Seqval seq: List[Int] = ...; seq.map(...) 将返回 List,等等。这并不总是可能的:例如String 被认为是Char 的集合,但"ab".map(x => x.toInt) 显然不能返回String。同样对于Map:如果您将map 每对变为非对,则无法得到Map 的返回;但是你将每一对映射到一对(Int, Int),所以Scala返回Map[Int, Int]。所以你不能同时得到(0, 1)(0, 2):它们将是重复的键。

为避免此问题,请先将您的地图转换为Seq[((Int, Int), String)]mp.toSeq.map(x => x._1)(或mp.keySet.toSeq)。

【讨论】:

  • 有趣,编译器不应该针对这种情况发出警告吗?这只是人们可能会出错的事情
  • 您如何将其与预期的情况(例如map.map { case (k, v) => (k, v + 1) })区分开来?显然,Map#map 不能直接删除;你可以尝试为它的弃用辩护,但我不希望成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 2013-04-27
  • 2012-12-23
  • 1970-01-01
  • 2013-05-08
  • 2014-01-30
相关资源
最近更新 更多