HashTrieMaps上的docs.scala-lang.org上阅读了此报价:



我认为这是一个很棒的(阅读:快速!)收藏品,用于存储我的Map [String,Long]。

在我的Play框架(使用Scala)中,我使用Anorm编写了这段代码,可加载约18k的元素。加载需要几秒钟的时间(没什么大不了,但是有什么提示吗?)。我想将其“存储在内存中”以快速查找字符串到长的翻译。

val data = DB.withConnection { implicit c ⇒
  SQL( "SELECT stringType, longType FROM table ORDER BY stringType;" )
    .as( get[String]( "stringType" ) ~ get[Long]( "longType " )
    map { case ( s ~ l ) ⇒ s -> l }* ).toMap.withDefaultValue( -1L )
}

此代码使data成为class scala.collection.immutable.Map$WithDefault类型。我希望它的类型为HashTrieMap(或HashMap,据我所知,所有Scala HashMaps的链接引用都属于HashTrieMap?)。奇怪的是,我找不到如何将其转换为HashTrieMap的方法。 (我是Scala,Play和Anorm的新手。)
// Test for the repl (2.9.1.final). Map[String, Long]:
val data = Map( "Hello" -> 1L, "world" -> 2L ).withDefaultValue ( -1L )
data: scala.collection.immutable.Map[java.lang.String,Long] =
  Map(Hello -> 1, world -> 2)

// Google showed me this, but it is still a Map[String, Long].
val hm = scala.collection.immutable.HashMap( data.toArray: _* ).withDefaultValue( -1L )

// This generates an error.
val htm = scala.collection.immutable.HashTrieMap( data.toArray: _* ).withDefaultValue( -1L )

所以我的问题是如何将MapWithDefault转换为HashTrieMap(如果共享HashTrieMap的实现,则转换为HashMap)?

欢迎任何反馈。

最佳答案

正如您所指向的文档所述,不可变映射已经在后台实现为HashTrieMap。您可以在REPL中轻松地验证这一点:

scala> println( Map(1->"one", 2->"two", 3->"three", 4->"four", 5->"five").getClass )
class scala.collection.immutable.HashMap$HashTrieMap

因此,您没有什么特别的事情要做,您的代码已经在使用HashMap.HashTrieMap了,甚至没有意识到。

更准确地说,immutable.Map的默认实现是immutable.HashMap,它由immutable.HashMap.HashTrieMap进一步完善(扩展)。
请注意,虽然小的不可变映射不是immutable.HashMap.HashTrieMap的实例,但是是作为特殊情况实现的(这是一种优化)。有一个特定的大小阈值,在这些阈值下它们开始被添加为immutable.HashMap.HashTrieMap
例如,在REPL中输入以下内容:
val m0 = HashMap[Int,String]()
val m1 = m0 + (1 -> "one")
val m2 = m1 + (2 -> "two")
val m3 = m2 + (3 -> "three")
println(s"m0: ${m0.getClass.getSimpleName}, m1: ${m1.getClass.getSimpleName}, m2: ${m2.getClass.getSimpleName}, m3: ${m3.getClass.getSimpleName}")

将打印此:
m0: EmptyHashMap$, m1: HashMap1, m2: HashTrieMap, m3: HashTrieMap

因此,这里的空映射是EmptyHashMap$的一个实例。向其添加元素将得到HashMap1,最后再添加另一个元素将得到HashTrieMap

最后,withDefaultValue的使用不会改变任何内容,因为withDefaultValue只会返回一个实例Map.WithDefault,该实例将初始映射包裹起来(仍将是HashMap.HashTrieMap)。

10-05 18:25