简体   繁体   English

在不同对象上调用相同方法时,返回类型不同

[英]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

DEMO 演示

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. 然后为每个元素将其添加到地图。

  • Empty map + new key is Map1 src 空地图+新密钥是Map1 src
  • Map1 + new key is Map2 src Map1 +新密钥是Map2 src
  • ... ...
  • Map4 + new key is HashMap src Map4 +新密钥是HashMap src

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM