scala - 为啥map.size在地图不为空时返回0

Posted

技术标签:

【中文标题】scala - 为啥map.size在地图不为空时返回0【英文标题】:scala - why map.size return 0 when the map is not emptyscala - 为什么map.size在地图不为空时返回0 【发布时间】:2017-10-13 04:13:42 【问题描述】:

我是 scala 的新手。下面的例子我有点困惑发生了什么。我创建了一个可变映射,然后将三个键/值推送到映射。我可以通过键检索带有值的队列,但“web.keys”显示地图为空,“web.size”返回 0!为什么会这样?如何检索正确的地图大小?

scala> import scala.collection.mutable.Map, Set, Queue, ArrayBuffer

scala> val web = Map[Int, Queue[Long]]().withDefaultValue(Queue()) 
web: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map()

scala> web(123).enqueue(567L)

scala> web(123).enqueue(1L)

scala> web(123).enqueue(2L)

scala> web(123)
res96: scala.collection.mutable.Queue[Long] = Queue(567, 1, 2)

scala> web
res97: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map()

scala> web.size
res98: Int = 0

scala> web.keys
res99: Iterable[Int] = Set()

一张简单的地图就可以了。

scala> val w= Map[Int,Int]()
w: scala.collection.mutable.Map[Int,Int] = Map()

scala> w(1)=1

scala> w
res10: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1)

scala> w(2)=2

scala> w
res12: scala.collection.mutable.Map[Int,Int] = Map(2 -> 2, 1 -> 1)

scala> w.size
res13: Int = 2

我尝试了更多的实验,似乎它与“withDefaultValue”有关。但是我该如何解决呢?

scala> val ww= Map[Int,Int]().withDefaultValue(0) 
ww: scala.collection.mutable.Map[Int,Int] = Map()

scala> ww
res14: scala.collection.mutable.Map[Int,Int] = Map()

scala> ww(1) += 1

scala> ww(2) += 2

scala>  w.size
res17: Int = 0

【问题讨论】:

Why does my Map claim to have no keys after adding keys? 或 Behaviour of withDefaultValue in mutable.Map 的可能重复 【参考方案1】:

当从地图返回默认值时,它不会添加到地图!所以当调用web(123)

没有添加任何东西到地图,只返回默认值。使用getOrElseUpdate 方法读取数据而不是使用默认值的地图。或者只是考虑到默认值不像其他键值对那样在映射中。

我认为你误解了你的例子:

在第一个示例web(123).enqueue(567L) 中,您正在检索默认值并将 567L 添加到默认值(队列)。地图中没有添加任何内容。

在第二个示例w(1)=1 中,您正在向地图添加数据

在第三个示例 ww(1) += 1 中,您正在检索默认值 (0) 并将其加 1。

一般使用map(K)会返回key K的值,而map(K) = V会设置key K的值V。

在底层调用 map(K)map(K) = V 使用 apply 和 update 方法。有关详细信息,请参阅 http://otfried.org/scala/apply.html 或其他 scala 文档。

【讨论】:

谢谢!我懂了。我认为它会像 python defaultdict 一样工作。 只是为了强调(当我看到这个时,这让我感到困惑)。如果你会做 web(124) 你仍然会得到排队的默认值。默认值是您正在更改的可变队列。

以上是关于scala - 为啥map.size在地图不为空时返回0的主要内容,如果未能解决你的问题,请参考以下文章

为啥我收到异常 Azure WebJobs SDK Dashboard connection string is missing or empty 当它根本不为空时?

仅在选中且不为空时才显示元素

MySQL - 仅在不为空时连接

仅当表不为空时,T-SQL 才连接表

Spring - 仅当值不为空时才设置属性

VBScript 仅在文件不为空时附加文件