​ 最近研究了下scala语言,这个语言最强大的就是它强大的函数式编程(Function Programming)能力,记录下最近学习的一些新的和技巧。注意:本系列博客不会从头讲解该语言的语法,而是通过一些例子讲解该语言的一些技巧,如果需要从头学习scala,建议使用该教程快速入门。

1 Map的基础操作

​ Map的初始化和添加元素操作,如果直接用Map来生成一个对象,那么默认生成的一个不可变对象map,因此,clear等对原有对象进行更改的方法都是不可用的。

   /**
* map的基础操作
*/
def basicMapOp(): Unit = {
var m:Map[String,String] = Map("key" -> "value")
//m("key1") = "value2" // 不支持这种用法
//增加一个键值对
m += ("key1" -> "value1")
println(m)
//如果不存在该键,那么选取默认值
var value = m.getOrElse("key2","defaultValue")
println(s"defaultValue:$value") //对原来的值进行更改
m += ("key1" -> "newValue1")
//合并两个集合
m ++= List("key2" -> "value2", "key3" -> "value3")
//合并的时候,如果存在相同的键(key1),那么会被右边的集合给覆盖掉
m ++= Map("key4" -> "value4", "key5" -> "value5", "key1" -> "valueFromNewMap")
println(m.get("key1"))
//删除一个元素
m -= "key1" var hashMap = mutable.HashMap("hello" -> "world")
hashMap += ("one" -> "two")
println("this is a hashmap! we will clear it!")
hashMap.clear() //注意,这里是不支持的,默认使用Map构造的是个Immutable,所以没有clear方法。
//m.clear //判断是否为空
if (hashMap.isEmpty) {
println("map is empty!")
}
else{
println("map is not empty!")
}
}

2 Map生成view和transform解析

​ Map的mapValues方法会生成一个view,该view会和原先的map关联紧密,并且该view是lazy的,也就是说,每次对该view进行操作(如遍历)的时候,该view才会对原先的map进行操作。来看一个例子:

object MapTest {

  val SEPERATOR = "----------------------"
class ObjClass {
def this(mem: String) = {
this()
this.member = mem
} //表示该函数返回类型为该类类型
def getSelf(): this.type = this var member: String = _ override def toString: String = s"$member"
} def main(args: Array[String]): Unit = {
println(SEPERATOR)
basicMapOp()
println(SEPERATOR) val originMap = Map(1 -> new ObjClass("one"))
println(SEPERATOR)
println(s"m = $originMap")
println(SEPERATOR) //返回的是一个view,并且该view和m强相关,后面每次调用m1,都会使得该view的mapValues被调用一次
val mapValueMap = originMap.mapValues { a => a.member = "two"; println("1:" + a.member); a }
println(s"m = $originMap") //m = one
println(s"m1=$mapValueMap") //1: two
mapValueMap.foreach { kv => kv._2.member = "three"; println("2:" + kv._2.member) } // 1:two 2:three
println(s"m1=$mapValueMap") // 1:two,导致view又重新运行一遍
println(SEPERATOR)
//而transform就不会出现mapValues中的view情况, m2每次被调用,不会到导致transform又重新被运行一次。
val transformMap = originMap.transform { (k, v) => v.member = "four"; v }
//added by seancheer: 注意,这里不带.也是可以的
//val m2 = m transform { (k, v) => v.f = "d"; v }
println(s"m=$originMap") //m = four
originMap.foreach { kv => kv._2.member = "five!"}
println(s"m2=$transformMap") // m2 = five, 返回的view是m的映射,因此修改m,m2也会被更新,同时,不会像mapValueMap那样,每调用一次,就运行一次
println(s"m=$originMap") //m = five
println(SEPERATOR)
} }

​ 可以看到,mapValues返回的投影是lazy型的,每次使用一次返回后的mapValueMap,都会导致mapValues后面的方法体运行一次,从而导致originMap中的元素被重新更新为"two",但是,transform方法返回的投影transformMap就没有这种情况。

​ 需要注意的是,这两个方法返回的都是originMap的一个投影(Projection),更新原始的originMap,会导致投影也发生变化。

Scala语言笔记 - 第二篇的更多相关文章

  1. Scala语言笔记 - 第一篇

    目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 ​ 最近研究了下scala ...

  2. Scala语言笔记 - 第三篇(容器方法篇)

    Scala语言笔记 - 第三篇(容器方法篇) 目录 Scala语言笔记 - 第三篇(容器方法篇) map和flapMap方法: ​ 最近研究了下scala语言,这个语言最强大的就是它强大的函数式编程( ...

  3. 《javascript权威指南》读书笔记——第二篇

    <javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...

  4. c#开发Mongo笔记第二篇

    写到第二篇不得不说是我之前犯了一个小错误,其实实现子表存储也是很简单的事,先说我想实现什么样的效果吧 就是用户表里有个成绩字段,成绩字段是个子表 其实实现这个功能也很简单,用面向对象的思想很好理解,子 ...

  5. 瘋子C语言笔记(指针篇)

    指针篇 1.基本指针变量 (1)定义 int i,j; int *pointer_1,*pointer_2; pointer_1 = &i; pointer_2 = &j; 等价于 i ...

  6. js学习笔记第二篇

    Js笔记整理 1.StringAPI a)        大小写转换:str.toUpperCase();str.toLowerCase(); b)        获取指定位置字符: Str[i]-- ...

  7. [Python笔记]第二篇:运算符、基本数据类型

    本篇主要内容有:运算符 基本数据类型等 一.运算符 1.算术运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 6.身份运算 7.位运算 8.运算符优先级 二.基本数据类型 1.整数:int ...

  8. Android学习笔记(第二篇)View中的五大布局

    PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念   view是什么呢?我们已经知道一个Act ...

  9. Node 之 Express 学习笔记 第二篇 Express 4x 骨架详解

    周末,没事就来公司加班继续研究一下Express ,这也许也是单身狗的生活吧. 1.目录结构: bin, 存放启动项目的脚本文件 node_modules, 项目所有依赖的库,以及存放 package ...

随机推荐

  1. [2021BUAA软工_助教博客]作业成绩汇总

    作业及成绩 作业链接 成绩链接 个人阅读作业#1 个人阅读作业#1_成绩 个人阅读作业#2 个人阅读作业#2_成绩 结对项目-第一阶段 结对项目-第一阶段_成绩 结对项目-第二阶段 结对项目-第二阶段 ...

  2. Swift系列七 - 汇编分析值类型

    通过汇编分下值类型的本质. 一.值类型 值类型赋值给var,let或者给参数传参,是直接将所有内容拷贝一份.类似于对文件进行复制粘贴操作,产生了全新的文件副本,属于深拷贝(deep copy). 示例 ...

  3. [DB] HDFS

    体系架构 NameNode HDFS主节点.管理员 接收客户端(命令行.Java程序)的请求:创建目录.上传.下载.删除数据 管理和维护HDFS的日志和元信息 日志文件(edits文件) 二进制文件, ...

  4. Linux_配置认证访问FTP服务

    [RHEL8]-FTPserver:[Centos8]-FTPclient !!!测试环境我们首关闭防火墙和selinux(FTPserver和FTPclient都需要) [root@localhos ...

  5. 四大浏览器JavaScript性能/硬件加速测试

    四大浏览器JavaScript性能/硬件加速测试 出处:快科技 2010-09-19 10:52:59    人气: 27925 次   作者:萧萧 编辑:萧萧[爆料]  评论(42)  收藏文章 新 ...

  6. 速度竟差9倍!6款32GB USB3.0优盘横评

    速度竟差9倍!6款32GB USB3.0优盘横评 2014-08-22 05:04:00  [  中关村在线 原创  ]   作者: 蒋丽 |  责编:孙玉亮 收藏文章 分页阅读 分享到 评论(90) ...

  7. 056.Python前端Django模型ORM多表基本操作

    一 准备工作 1.1 新建一个项目 root@darren-virtual-machine:~# cd /root/PycharmProjects/ root@darren-virtual-machi ...

  8. linux中级之lvs配置(命令)

    一.nat模式配置 环境说明: DS:nat网卡(自动获取也可以,充当vip): 192.168.254.13 255.255.255.0 vmnet3网卡(仅主机): 172.16.100.1 25 ...

  9. Angular环境搭建及简单体验

    一.安装开发环境 npm install -g typescript npm install -g @angular/cli 二.创建hello-world项目 创建项目 ng new angular ...

  10. mysql数据库-运维合集

    目录 RDBMS 术语 整删改查操作 库操作 表操作 账号与授权 匹配符(条件查询) MySQL三大类数据类型 函数 其他操作 查看数据库的占用空间大小 开启慢查询 状态查询 字符集设置 忘记密码重置 ...