[英]Return type is different when invoking the same method on different objects
I wrote the following application: 我编写了以下应用程序:
var counters: mutable.Map[String, mutable.Map[String, Long]] = mutable.Map()
counters("key1") = mutable.Map("counters_key"→ 20)
counters("key2") = mutable.Map("counters_key" → 920)
counters("key3") = mutable.Map("counters_key" → 920)
counters("key4") = mutable.Map("counters_key" → 920)
counters("key5") = mutable.Map("counters_key" → 920)
var counters2: mutable.Map[String, mutable.Map[String, Long]] = mutable.Map()
counters2("key1") = mutable.Map("counters2_key_1"→ 112000, "counters_key_2" → 1112000, "counters_key_3"→ 20)
counters2("key2") = mutable.Map("counters2_key_4" → 9112000, "counters_key_5" → 91112000, "counters_key_6" → 920)
val flattenedCounters = counters.toMap.values.flatten
val flattenedCounters2 = counters2.toMap.values.flatten
println(flattenedCounters.getClass == flattenedCounters2.getClass)
//true
println(flattenedCounters.groupBy(_._1).getClass ==
flattenedCounters2.groupBy(_._1).getClass)
//false
We are invoking the same method on the 2 objects which are of the same type. 我们正在相同类型的2个对象上调用相同的方法。 But it gives us objects of different types.
但这给了我们不同类型的对象。 Why?
为什么?
The key is in the size of counters 关键在于柜台的大小
val map = counters.toMap
println(map.getClass)
//class scala.collection.immutable.HashMap$HashTrieMap
println(map.size)
//5
val map2 = counters2.toMap
println(map2.getClass)
//class scala.collection.immutable.Map$Map2
println(map2.size)
//2
Looks like Scala has several implementations for Map
. 看起来Scala有一些
Map
实现。 Map2
is optimized to hold exactly 2 elements. Map2
经过优化,可精确容纳2个元素。 And there are optimized implementations up to Map4
并且有多达
Map4
优化实现
You can find those classes in sources 您可以在源代码中找到这些类
When you call toMap
it creates new builder that holds empty map. 调用
toMap
它会创建一个包含空地图的新生toMap
。 Then for each element adds it to the map. 然后为每个元素将其添加到地图。
As pointed out by @Nazarii Bardiuk, it's due to the difference in the immutable Map size. 正如@Nazarii Bardiuk指出的,这是由于不变的地图尺寸不同所致。 Scala optimizes small Maps by storing them as single objects with elements as fields and implements larger Maps as HashMap , which uses
HashTrieMap
. Scala通过将小地图存储为元素作为字段的单个对象来优化小地图,并将大地图实现为HashMap ,后者使用
HashTrieMap
。
Here's quote under section Hash Tries
from a relevant Scala doc : 以下是来自相关Scala文档的
Hash Tries
部分下的引用:
Scala has a further optimization for immutable sets and maps that contain less than five elements.
Scala对包含少于五个元素的不可变集和映射进行了进一步优化。 Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields.
具有一到四个元素的集合和映射存储为单个对象,这些对象仅包含元素(或在映射的情况下为键/值对)作为字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.