2011-06-21 30 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