Scala语言笔记 - 第二篇
最近研究了下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语言笔记 - 第二篇的更多相关文章
- Scala语言笔记 - 第一篇
目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 最近研究了下scala ...
- Scala语言笔记 - 第三篇(容器方法篇)
Scala语言笔记 - 第三篇(容器方法篇) 目录 Scala语言笔记 - 第三篇(容器方法篇) map和flapMap方法: 最近研究了下scala语言,这个语言最强大的就是它强大的函数式编程( ...
- 《javascript权威指南》读书笔记——第二篇
<javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...
- c#开发Mongo笔记第二篇
写到第二篇不得不说是我之前犯了一个小错误,其实实现子表存储也是很简单的事,先说我想实现什么样的效果吧 就是用户表里有个成绩字段,成绩字段是个子表 其实实现这个功能也很简单,用面向对象的思想很好理解,子 ...
- 瘋子C语言笔记(指针篇)
指针篇 1.基本指针变量 (1)定义 int i,j; int *pointer_1,*pointer_2; pointer_1 = &i; pointer_2 = &j; 等价于 i ...
- js学习笔记第二篇
Js笔记整理 1.StringAPI a) 大小写转换:str.toUpperCase();str.toLowerCase(); b) 获取指定位置字符: Str[i]-- ...
- [Python笔记]第二篇:运算符、基本数据类型
本篇主要内容有:运算符 基本数据类型等 一.运算符 1.算术运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 6.身份运算 7.位运算 8.运算符优先级 二.基本数据类型 1.整数:int ...
- Android学习笔记(第二篇)View中的五大布局
PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念 view是什么呢?我们已经知道一个Act ...
- Node 之 Express 学习笔记 第二篇 Express 4x 骨架详解
周末,没事就来公司加班继续研究一下Express ,这也许也是单身狗的生活吧. 1.目录结构: bin, 存放启动项目的脚本文件 node_modules, 项目所有依赖的库,以及存放 package ...
随机推荐
- Convert character array to string in MATLAB
Matlab提取特征值是经常要读取多个图片文件,把文件名保存在数组中后再读取会出错.从stackoverflow中找到如下解决方法: I've a M by N matrix, each cell c ...
- oo——第三单元总结
前言 第三单元是我们学习oo以来第一次接触JML.这一单元的三次作业和以前一样,采用了难度递进的方式,而且前一次作业的设计思路在下一次作业都多多少少有些体现(或者说是在其基础上做出的改进).而且本单元 ...
- ES6中的展开运算符和解构对象
let obj = { a:1 b:2 } let obj2 = { ...obj c:3 d:4 } console.log(obj2)//1,2,3,4,对象展开 //常考题目 let a = 1 ...
- Python运算符 - Python零基础入门教程
目录 一.算术运算符 二.赋值运算符 三.比较运算符 四.运算符的优先等级 五.重点总结 六.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python ...
- Linux_计划任务理论概述
一.计划任务概述 1.计划任务概述: 计划任务分为: 一次性任务 周期性任务 在Linux系统的计划任务服务crond 可以满足周期性执行任务的需求. crond进程每分钟会处璇一次计划任务,计划任务 ...
- IT菜鸟之虚拟机VMware的安装
老师说过,如果想学好Linux,最好不要在实体机上安装Linux,因为学习需要经常折腾,在实体机上做实验,出现故障就要重新安装,这样绝大多数时间都会浪费在安装上. 这时我们需要一个工具,它就是虚拟机. ...
- Linux进阶之日志管理
一.何为日志 1.在程序执行时,可以通过标准输出以及错误输出,让我们知道程序的执行情况,而系统不可能将所有程序的输出信息一起显示,要知道后台执行的程序非常之多,如果一起显示,那我们不用操作了,整天只看 ...
- Java Stream 流(JDK 8 新特性)
什么是 Steam Java 8 中新增了 Stream(流)来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作. 我们知道,Java 中 List 和 S ...
- IDEA 快速上手指南(全配置)(Day_23)
Idea快速入门指南 1.安装 1.1.安装 我们使用的是2017.3.4版本: 双击打开, 选择一个目录,最好不要中文和空格: 然后选择桌面快捷方式,请选择64位: 然后选择安装: 开始安装: 然后 ...
- sublime使用与配置
目录 Download Markdown转浏览器显示 1. 简单版本 2. 有MD全格式版本 Install Package Control 删除文本空行 1. Ctrl + H 2. Find \s ...