如何从scala树映射设置和获取关键点?

如何从scala树映射设置和获取关键点?,scala,treemap,Scala,Treemap,如果我有 import scala.collection.immutable.TreeMap val tree = new TreeMap[String, List[String]] 现在在上面的声明之后,我想把键“k1”分配给List(“foo”,“bar”) 那么,我如何获取或读回键“k1”以及读回不存在的键“k2” 如果我尝试读取不存在的键“k2”,会发生什么情况?对不可变的映射进行“变异”的最佳方法是在变量中引用它(var,而不是val): 可以使用apply方法直接访问它,其中sc

如果我有

import scala.collection.immutable.TreeMap

val tree = new TreeMap[String, List[String]]
现在在上面的声明之后,我想把键“k1”分配给List(“foo”,“bar”) 那么,我如何获取或读回键“k1”以及读回不存在的键“k2”

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

不可变的映射进行“变异”的最佳方法是在变量中引用它(
var
,而不是
val
):

可以使用
apply
方法直接访问它,其中scala语法糖起作用,因此您可以使用parens进行访问:

val l = tree("k1") //equivalent to tree.apply("k1")
但是,我很少访问这样的映射,因为如果密钥不存在,该方法将抛出
MatchError
。改为使用
get
,它返回一个
选项[V]
,其中
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
collect
getOrElse
。尝试并避免模式匹配,或使用
选项。直接获取
方法

例如:

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

编辑:构建地图而不将其声明为
var
,并且假设您通过转换某个单独的集合来实现这一点的一种方法是通过折叠。例如:

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

这对于您的用例可能不可能

scala中的AFAIK val意味着我们无法更改val指向的对象的引用,但我们可以更改对象中的值。因此,在上述情况下,更高性能的解决方案是基于val而不是var的。@amc-只有在可变结构提供更高性能的情况下(当然)才可能提供更高性能。此外,即使单个调用的性能更高,其他要求(例如,将集合安全地传递给程序的另一部分)也可能与此冲突-例如,您可能需要经常复制可变结构。还值得指出的是,scala标准库中没有可变的
TreeMap
。感谢您的代码,但有没有办法在保持树为val而不是var的同时做到这一点?@amc。不您很难将不可变的集合声明为不可变的
val
,然后期望对其进行变异。唯一可用的选项是仅在构建地图的最终版本后才声明
val
引用,或者使用scalaz的ST线程(不适用于胆小鬼)。@ziggystar-我希望你为自己感到羞耻
//coll is some collection class CC[A]
//f : A => (K, V)
val m = (TreeMap.empty[K, V] /: coll) { (tree, c) => tree + f(c) }