默认情况下在使用“Set”或“Map”的时候,获得的都是不可变对象。如果需要的是可变版本,需要先写明引用。

如果同一个源文件中既要用到可变版本,也要用到不可变版本的集合或映射,方法之一是引用包含了可变版本的包名:

scala> import scala.collection.mutable
import scala.collection.mutable

与以往一样, 不可变集可以用Set指代,但现在还可以用mutable.Set指代可变集。举例如下:

scala> val mutaSet = mutable.Set(1, 2, 3)
mutaSet: scala.collection.mutable.Set[Int] = Set(1, 2, 3)

使用集

集的关键特性在于它可以对使用对象的==操作检查,确保在任何时候每个对象只在集中保留最多一个副本。例如,我们可以用集对字符串不同单词计数。

如果指定空格和标点符号为单词的分隔符,String的split方法可以把字符串分割成单词。正则表达式“[  ! , .]“足以完成该功能:它表明字符串应该在每个存在一到多个空格或标点符号的地方分割开来:

scala> val text = "See Spot run. Run, Spot. Run!"
text: String = See Spot run. Run, Spot. Run!scala> val wordsArray = text.split("[ !,.]+")
wordsArray: Array[String] = Array(See, Spot, run, Run, Spot, Run)

要对不同的单词计数,可以先把它们变成同样的大小写然后加到集中。由于集不能重复添加,因此不同的单词只在集中出现一次。首先,可以使用Set伴生对象提供的empty方法创建空集:

scala> val words = mutable.Set.empty[String]
words: scala.collection.mutable.Set[String] = Set()

然后,用for表达式枚举所有的单词,分别把它们转换为小写字母形式,然后使用+=操作符添加到可变集中:

scala> for (word <- wordsArray)words += word.toLowerCasescala> words
res2: scala.collection.mutable.Set[String] = Set(see, run, spot)

使用映射

映射可以用来把值与集合中的元素联系起来。映射的使用与数组接近,只是你可以用任何类型的键,而不仅仅是使用从0开始计数的整数做索引。如果引用了scala.collection.mutable包,你还可以创建空的可变映射:

scala> val map = mutable.Map.empty[String, Int]
map: scala.collection.mutable.Map[String,Int] = Map()

映射中的条目设置与数组中的类似:

scala> map("hello") = 1scala> map("there") = 2scala> map
res5: scala.collection.mutable.Map[String,Int] = Map(hello -> 1, there -> 2)

类似的,读取映射和读取数组也是一样的:

scala> map("hello")
res6: Int = 1

把上面的例子放在一起,就有了下面对字符串中单词出现次数做计数的方法:

scala> def countWords(text: String) = {| val counts = mutable.Map.empty[String, Int]| for (rawWord <- text.split("[ ,!.]+")) {| val word = rawWord.toLowerCase| val oldCount =| if (counts.contains(word)) counts(word)| else 0| counts += (word -> (oldCount + 1))| }| counts| }
countWords: (text: String)scala.collection.mutable.Map[String,Int]scala> countWords("See Spot run! Run, Spot. Run!")
res7: scala.collection.mutable.Map[String,Int] = Map(spot -> 2, see -> 1, run ->3)

有序的集和映射
scala的集合库提供了SortedSet和SortedMap特质。这两个特质分别由类TreeSet和TreeMap实现,他们都使用了红黑树有序地保存元素(TreeSet类)或键(TreeMap类)。具体的顺序取决于Ordered特质,集的元素类型或映射的键类型必须要么混入,要么能够隐式地转换成Ordered特质。这些类只有不可变类型的版本。下面是TreeSet的例子:

scala> import scala.collection.immutable.TreeSet
import scala.collection.immutable.TreeSetscala> val ts = TreeSet(9, 3, 1, 8, 0, 2, 7, 4, 6, 5)
ts: scala.collection.immutable.TreeSet[Int] = TreeSet(0, 1, 2, 3, 4, 5, 6, 7, 8,9)scala> val cs = TreeSet('f', 'u', 'n')
cs: scala.collection.immutable.TreeSet[Char] = TreeSet(f, n, u)

下面是TreeMap的例子:

scala> import scala.collection.immutable.TreeMap
import scala.collection.immutable.TreeMapscala> var tm = TreeMap(3 -> 'x', 1 -> 'x', 4 -> 'x')
tm: scala.collection.immutable.TreeMap[Int,Char] = Map(1 -> x, 3 -> x, 4 -> x)scala> tm += (2 -> 'x')scala> tm
res9: scala.collection.immutable.TreeMap[Int,Char] = Map(1 -> x, 2 -> x, 3 -> x,4 -> x)

同步的(Synchronized)集和映射

如果需要线程安全的映射,可以把SynchronizedMap特质混入到你想要的特质类实现中。下面是一个吧SynchronizedMap混入HashMap的例子:

import scala.collection.mutable.{Map, SynchronizedMap, HashMap}object MapMaker {def makeMap: Map[String, String] = {new HashMap[String, String] with SynchronizedMap[String, String]{override def default(key: String) ="Why do you want to know?"}}
}

如果你请求映射返回与特定键关联的值,而该键的映射实际不存在,默认你将得到NoSuchElementException。然而如果你定义了新的映射类并重载了default方法,那么这个新的映射将在查询不存在的键时返回default方法的返回值。根据上面的代码,由编译器构造的合成HashMap子类将在查询不存在的键时返回”Why do you want to know?"。
下面的例子演示了在解释器中,单线程访问映射的情况:

scala> import scala.collection.mutable.{Map, SynchronizedMap, HashMap}
import scala.collection.mutable.{Map, SynchronizedMap, HashMap}scala> object MapMaker {|   def makeMap: Map[String, String] = {|     new HashMap[String, String] with SynchronizedMap[String, String]{|       override def default(key: String) =|         "Why do you want to know?"|     }|   }| }
warning: there was one deprecation warning; re-run with -deprecation for detailsdefined object MapMakerscala> val capital = MapMaker.makeMap
capital: scala.collection.mutable.Map[String,String] = Map()scala> capital ++ List("US" -> "Washington", "Paris" -> "France", "Japan" -> "To
kyo")
res10: scala.collection.mutable.Map[String,String] = Map(Paris -> France, Japan
-> Tokyo, US -> Washington)scala> capital("Japan")
res11: String = Why do you want to know?scala> capital += ("New Zealand" -> "Wellington")
res12: capital.type = Map(New Zealand -> Wellington)scala> capital("New Zealand")
res13: String = Wellington

你可以按照与创建同步映射类似的方法创建同步集。例如可以通过混入SynchronizedSet特质创建同步的HashSet,见下:

scala> import scala.collection.mutable
import scala.collection.mutablescala> val synchroSet =| new mutable.HashSet[Int] with | mutable.SynchronizedSet[Int]
warning: there was one deprecation warning; re-run with -deprecation for detailssynchroSet: scala.collection.mutable.HashSet[Int] with scala.collection.mutable.SynchronizedSet[Int] = Set()

scala编程第17章学习笔记(2)——集和映射相关推荐

  1. scala编程第16章学习笔记(1)

    List列表的基本操作 head方法获得列表的第一个元素 tail方法获得列表除第一个元素之外的其它元素 isEmpty:判断列表是否为空,空的话返回真 last:获得列表最后一个元素 init:获得 ...

  2. scala编程第18章学习笔记——有状态的对象

    银行账号的简化实现: scala> class BankAccount{| private var bal: Int = 0| def balance: Int = bal| def depos ...

  3. scala编程第16章学习笔记(3)——List类的高阶方法

    列表间映射:map.flatMap和foreach 1.xs map f 操作返回把函数f应用在xs的每个列表元素之后由此组成的新列表.如: scala> List(1, 2, 3) map ( ...

  4. 《小马哥讲Spring核心编程思想》-第一章学习笔记(1)

    <小马哥讲Spring核心编程思想>-第一章学习笔记(1) 一.课程介绍 1.为什么要学习spring? 2.深入学习spring的难点有哪些? 3.课程的设计思路是怎样的? 二.内容综述 ...

  5. 《构建之法》第4.17章读书笔记

    <构建之法>第4.17章读书笔记 第四章 原文语句: 异常不能跨过DLL或进程的边界来传递信息,所以异常不是万能的. 提出问题: 1.什么是DLL?DLL是来解决什么问题的? 网上说法: ...

  6. C++程序设计教程(钱能)第四章 学习笔记

    C++程序设计教程(钱能)第四章 学习笔记 4.1 名词解释与操作符 4.1.1 名词解释 4.1.2 操作符汇总 4.1.3 操作符的说明 4.2 算数运算问题 4.2.1 周而复始的整数 4.2. ...

  7. NVIDIA可编程推理加速器TensorRT学习笔记(二)——实操

    NVIDIA可编程推理加速器TensorRT学习笔记(二)--实操 ​ TensorRT 是 NVIDIA 自家的高性能推理库,其 Getting Started 列出了各资料入口,如下: 本文基于博 ...

  8. 知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别

    知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别 知识图谱的概念,与传统语义网络的区别 狭义概念 作为语义网络的内涵 与传统语义网络的区别 优点 缺点 与 ...

  9. 工程伦理第三章学习笔记2020最新

    工程伦理第三章学习笔记2020最新 因为之前自己在网上找答案总是觉得费劲,一道一道的找,很慢,突然找到了前两章的答案,感觉有一种前人种树后人乘凉的感觉,于是自己在艰难找完第三章习题并全对的情况下,将题 ...

最新文章

  1. Oracle-PL/SQL语法基础
  2. redis做分布式锁可能不那么简单
  3. Anaconda卸载与重装过程记录
  4. 微信公众帐号开发教程第10篇-解析接口中的消息创建时间CreateTime
  5. ssh 认证指定端口
  6. Centos 6.3中安装KVM
  7. mac maven安装与配置镜像
  8. websphere多应用域名绑定
  9. U盘引导盘制作工具---Rufus
  10. unity3d2018版skybox在哪里
  11. 【Spring】IoC与AOP
  12. 财宝通告诉你如何利用网络POS机及时到账功能养卡
  13. 王者荣耀用什么开发的
  14. google爬取搜索结果
  15. Win10配置adb环境
  16. fwrite和fread函数的用法小结
  17. 今天看到一篇过千粉条友的懊悔分享
  18. 美团java工程师,成都外包面试笔试题
  19. 微信小程序居家养老+后台管理系统
  20. soc是单片机发展的第三个阶段

热门文章

  1. JVM常见垃圾收集器
  2. pta l2-1紧急救援(Dijkstra)
  3. Spring Tool Suite插件的安装
  4. POJ 2229 Sumsets(递推,找规律)
  5. IOS实现打电话后回调
  6. 删除某个目录及目录下的所有子目录和文件
  7. 李开复:21世纪最需要的7种人才
  8. 9-3 数据分布概论
  9. LPS最长回文子序列
  10. 第8章 函数探索