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 ...
随机推荐
- SpringBoot简单尝试
一.spring boot核心 配置在类路径下autoconfigure下(多瞅瞅) @SpringBootApplication里的重要注解(@Configuration,@EnableAutoCo ...
- Blazor实现未登录重定向到登录页的方法
今天研究了一下blazor,发现他默认启动就是类似于后台管理系统的界面,看到这个页面我就想给他写个登录,有登录就涉及到未登录重定向的问题,但是我没有找到blazor全局路由的设置,知道的老哥可以告诉我 ...
- Redis学习笔记六:持久化实验(AOF,RDB)
作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...
- libminipng,压缩png的swift-framework
libminipng 通过lodepng解析png图片,使用pngquant算法进行压缩的swift-framework 方法说明: /// 通过PNG图片Data压缩 /// /// - Param ...
- 【待写Java线程之线程终止 Interrupt 】
参考:https://bbs.csdn.net/topics/280082639 interrupt()方法不会中断一个正在运行的线程.这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线 ...
- linux动态链接库和静态链接库
Linux下静态链接库与动态链接库的区别 引言 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件 (object file)与牵涉到的函数库(librar ...
- IDEA 快速上手指南(全配置)(Day_23)
Idea快速入门指南 1.安装 1.1.安装 我们使用的是2017.3.4版本: 双击打开, 选择一个目录,最好不要中文和空格: 然后选择桌面快捷方式,请选择64位: 然后选择安装: 开始安装: 然后 ...
- 技术干货 | 关于 WKWebview 网络拦截,你想知道的都在这里
原生 WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此在 WKWebView 上直接使用 NSURLProtocol 是无法拦截请求的. 但是由于 mPa ...
- kylin的rowkey优化之调整rowkey顺序
在以hbase为存储的cuboid中,会有很多计算好的数据行,这每个行的key都是由维度值按顺序生成的rowkey 而这个顺序,在我们做cube设计的时候是可以调整的. 具体调整路径是:cube de ...
- 行者APP适配国外环境问题解决
(本文1151字,阅读约5分钟) 玩骑行的同伴都知道,长途骑行,第一需要好的硬件,如大腿发动机.车子.装备等:二是需要好的软件,如意志.有氧能力.骑行app等. 到雅加达后,才发现在国内用了几年的黑鸟 ...