加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:如何从地图制作哈希(Trie)地图(通过播放中的Anorm)

发布时间:2020-12-16 09:53:06 所属栏目:安全 来源:网络整理
导读:在 docs.scala-lang.org HashTrieMaps阅读此报价: For instance,to find a given key in a map,one first takes the hash code of the key. Then,the lowest 5 bits of the hash code are used to select the first subtree,followed by the next 5 bits an
在 docs.scala-lang.org HashTrieMaps阅读此报价:

For instance,to find a given key in a map,one first takes the hash code of the key. Then,the lowest 5 bits of the hash code are used to select the first subtree,followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level.

我认为这是一个很棒的(读取:快!)集合来存储我的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 )
}

此代码生成类型为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(或HashMap,如果它共享HashTrieMap的实现)?

任何反馈欢迎.

解决方法

正如您指出的文档所解释的那样,不可变映射已经在HashTrieMaps下实现.您可以在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).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读