2011-06-21 32 views
5

假设我有如何设置和从Scala TreeMap获取密钥?

import scala.collection.immutable.TreeMap 

val tree = new TreeMap[String, List[String]] 

现在上面的声明之后,我想指定密钥“K1”到列表(“富”,“酒吧”) 然后我如何得到或读回键“K1 “还读回不存在的密钥”k2“?

如果我尝试读取不存在的密钥“k2”,会发生什么情况?

回答

11

至“突变”的不可改变地图是通过参照它在一个变量(var相对于val)的最佳方式:

var tree = TreeMap.empty[String, List[String]] 
tree += ("k1" -> List("foo", "bar")) //a += b is sugar for "c = a + b; a = c" 

它可以直接使用apply方法,其中被访问在这样的Scala语法糖踢你可以访问使用括号:

val l = tree("k1") //equivalent to tree.apply("k1") 

不过,我很少像这样访问的地图,因为该方法将抛出一个MatchError是柯y不存在。使用get代替,其中V是价值型返回一个Option[V]

val l = tree.get("k1") //returns Option[List[String]] = Some(List("foo", "bar")) 
val m = tree.get("k2") //returns Option[List[String]] = None 

在这种情况下,对于一个缺席键返回的值是None。我该怎么办可选结果?那么,你可以使用方法map,flatMap,filter, collectgetOrElse。尝试并避免模式匹配,或直接使用Option.get方法!

例如:

val wordLen : List[Int] = tree.get("k1").map(l => l.map(_.length)) getOrElse Nil 

编辑:建设一个地图没有宣布它作为一个var,假设你是通过将一些单独收集这样的一个办法,就是做它通过折叠。例如:

//coll is some collection class CC[A] 
//f : A => (K, V) 
val m = (TreeMap.empty[K, V] /: coll) { (tree, c) => tree + f(c) } 

这可能不适合你的使用情况有可能

+0

AFAIK VAL在斯卡拉意味着我们不能改变引用到VAL所指向的对象,但我们可以改变对象的值。所以更高性能的解决方案是基于val而不是以上情况下的var。 – ace

+0

@amc - 只有当可变结构提供更高的性能时,(当然)它可能不会。此外,即使单个调用的性能更高,其他需求(例如安全地将集合传递给程序的另一部分)也可能与此冲突 - 例如,您可能必须经常采用可变结构的**副本** 。值得指出的是,在scala标准库中没有可变的'TreeMap'。 –

+0

谢谢你的代码,但有没有办法做到这一点,而保持树为VAL而不是VAR? – ace