Scala学习笔记(三)

Scala的基础语法

继上一篇的基础语法之后,我又整理了一些个人学习过程中认为比较重要的语法。

1. if/else 表达式

1.1 替代三目运算符

先用 Java 来写一段三目运算符的代码

int i = 10;
int j = i>5?i:5

Scala 由于没有 Java 的三目运算符(?:),不过好在可以用 if/else 表达式替代它。

scala> val i = 10
i: Int = 10

scala> val j = if (i>5) i else 5
j: Int = 10

上面的代码,还可以写成

scala> val i = 10
i: Int = 10

scala> var j =0
j: Int = 0

scala> if (i>5) j = i else j=5

scala> println (j)
10

不过,这种写法变量 j 需要定义成 var,因为 val 的变量一旦定义不能被改变略嫌麻烦 , 所以第一种写法会更好。

1.2 混合类型表达式

scala> val i = 10
i: Int = 10

scala> val j = if (i>5) "String express" else 5
j: Any = String express

scala> println(j)
String express

一般三目运算符肯定是返回同一种类型,但是上述的代码在 if 和 else 里既有String类型又有Int类型。所以,返回的是两个类型的公共超类型Any。

2. 占位符_

Scala 可以把下划线“_”当做一个或多个参数的占位符,第一个下划线代表第一个参数,第二个下划线代表第二个,以此类推。只要每个参数在函数文本内仅出现一次。

先看一段 Java 的代码,它将集合的每个元素都乘以2再打印出来。

Integer[] arrays = {1,2,3,4,5};
List<Integer> list = Arrays.asList(arrays);
list.stream().map(it->it*2).forEach(System.out::println);

再用占位符来简化上述的 Java 代码

scala> val list = Array(1,2,3,4,5)
list: Array[Int] = Array(1, 2, 3, 4, 5)

scala> list.map(_*2).foreach(println)
2
4
6
8
10

通过对比,显然 Scala 的代码更加简洁。

再来一个例子:多个占位符

scala> val f1 = (x:Int,y:Int) => x+y
f1: (Int, Int) => Int = $$Lambda$1011/349978505@1706a5c9

scala> f1(1,2)
res0: Int = 3

用两个占位符来简化上面的代码。

scala> val f2 = (_:Int)+(_:Int)
f2: (Int, Int) => Int = $$Lambda$1034/74606989@7b7683d4

scala> f2(1,2)
res1: Int = 3

3. Array 、 ArrayBuffer 以及多维数组

Scala 的数组包括定长数组 Array,以及不定长数组 ArrayBuffer。

3.1 Array

scala> val nums = new Array[Int](10) // 所有元素初始化为0
nums: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> val strings = new Array[String](10) // 所有元素初始化为null
strings: Array[String] = Array(null, null, null, null, null, null, null, null, null, null)
scala> val names = Array("tony", "cafei", "aaron")
names: Array[String] = Array(tony, cafei, aaron)

scala> names(0)
res2: String = tony

一旦初始化 Array ,只能修改 Array 中的元素,不能增加或者删除元素。

3.2 ArrayBuffer

ArrayBuffer类似 Java 中的ArrayList。它是数组缓冲。

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

scala> val arrayBuffer = new ArrayBuffer[Int]
arrayBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> arrayBuffer += 0
res7: arrayBuffer.type = ArrayBuffer(0)

scala> arrayBuffer += 1
res8: arrayBuffer.type = ArrayBuffer(0, 1)

scala> arrayBuffer += (2,3,4,5)
res9: arrayBuffer.type = ArrayBuffer(0, 1, 2, 3, 4, 5)

scala> arrayBuffer ++= Array(6,7,8,9,10) // 添加Array需要使用++
res10: arrayBuffer.type = ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> arrayBuffer.trimEnd(1) // 删除最后一个元素

scala> println (arrayBuffer)
ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

ArrayBuffer 还支持在任意位置进行添加(insert)和删除(remove)操作

scala> arrayBuffer.insert(2,100) // 在下标2处插入100

scala> println (arrayBuffer)
ArrayBuffer(0, 1, 100, 2, 3, 4, 5, 6, 7, 8, 9)

scala> arrayBuffer.insert(5,101,102) // 在下标5处插入101,102

scala> println (arrayBuffer)
ArrayBuffer(0, 1, 100, 2, 3, 101, 102, 4, 5, 6, 7, 8, 9)

反之,ArrayBuffer 的 remove 操作是同理。

除此之外, ArrayBuffer 还有 sum、max、min、sorted 等常用函数。

ArrayBuffer 到 Array 的转换: toArray

scala> arrayBuffer.toArray
res21: Array[Int] = Array(0, 1, 100, 2, 3, 101, 102, 4, 5, 6, 7, 8, 9)

3.3 多维数组

Scala 多维数组是通过数组的数组来实现的。二维数组看起来像是Array[Array[Int]]。要构造这样一个数组,可以用ofDim方法。

二维数组的定义

scala> val matrix=Array.ofDim[Int](3,4) 
matrix: Array[Array[Int]] = Array(Array(0, 0, 0, 0), Array(0, 0, 0, 0), Array(0, 0, 0, 0))

三维数组的定义

scala> val matrix2 = Array.ofDim[Int](3,4,5)
matrix2: Array[Array[Array[Int]]] = Array(Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)), Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)), Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)))

所以,多维数组的定义:
Array.ofDim[类型](维度1, 维度2, 维度3,....)

4. 不可变Map 和 可变Map

4.1 不可变Map

不可变Map位于scala.collection.immutable包中。

假设,我们定义某学生的期末考试分数,它是一个不可改变的Map集合。

scala> val scores = Map("math"->90,"english"->85,"chinese"->80)
scores: scala.collection.immutable.Map[String,Int] = Map(math -> 90, english -> 85, chinese -> 80)

获取该学生的数学成绩

scala> scores("math")
res8: Int = 90

获取该学生的计算机成绩,其实并没有录入计算机课程的分数会出现什么情况呢?

scala> scores("computer")
java.util.NoSuchElementException: key not found: computer
  at scala.collection.immutable.Map$Map3.apply(Map.scala:156)
  ... 30 elided

不出意外地报了一个错误。
所以,我们得先判断一下map里是否包含计算机课程,包含的话就取出成绩,不包含的话只能默认0分,这样代码才安全。

scala> val computer = if (scores.contains("computer")) scores("computer") else 0
computer: Int = 0

这下,命令行就不会报错了。

4.2 可变Map

可变Map位于scala.collection.mutable包中。
对于刚才的情况,添加该学生计算机的成绩。

scala> scores +=("computer"->88)
<console>:13: error: value += is not a member of scala.collection.immutable.Map[String,Int]
       scores +=("computer"->88)

scala是会报错的,因为scores是不可变map。

重新定义scores,让它变成可变的map,这样就可以添加其他课程的成绩了。

scala> val scores = scala.collection.mutable.Map("math"->90,"english"->85,"chinese"->80)
scores: scala.collection.mutable.Map[String,Int] = Map(chinese -> 80, math -> 90, english -> 85)

scala> scores +=("computer"->88)
res12: scores.type = Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)

换一个角度,我们来看看如何定义一个空的Map


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

scala> map += ("computer"->88)
res15: map.type = Map(computer -> 88)

scala> map +=  ("math"->90,"english"->85,"chinese"->80)
res16: map.type = Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)

scala> println (map)
Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)

scala> map.getClass
res18: Class[_ <: scala.collection.mutable.HashMap[String,Int]] = class scala.collection.mutable.HashMap

未来,我会单独再整理一篇集合相关的文章。

5. 元组

元组(Tuple)是不同类型的值的聚集。

定义一个元组:

scala> val tuple = (0,false,"Scala")
tuple: (Int, Boolean, String) = (0,false,Scala)

然后我们可以用方法_1、_2、_3访问其元素。

scala> println(tuple._1) // 打印第一个元素
0

scala> println(tuple._2) // 打印第二个元素
false

scala> println(tuple._3) // 打印第三个元素
Scala

值得注意的是,元组的索引是从1开始,而数组的索引是从0开始。

通常,使用模式匹配来获取元组的元素。

scala> val (first, second, third)=tuple
first: Int = 0
second: Boolean = false
third: String = Scala

如果并不是所有的元素都需要,那么可以在不需要的元素位置上使用占位符_:

scala> val (first, second, _ ) = tuple
first: Int = 0
second: Boolean = false

总结

这篇笔记还是整理一些基础的知识。

下一篇开始,我会整理 Scala 的类相关的内容。

先前的文章:
Scala学习笔记(二)
Scala学习笔记(一)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • scala学习笔记 第2章 变量和数据类型 基本数据 scala的核心数据为四种 :字面量、值、变量、类型 值使...
    485b1aca799e阅读 2,101评论 0 1
  • 数组 :new Array[Int](8)与Array[Int](8)的区别:第一种8个元素,第二个定义一个值为8...
    夙夜M阅读 1,742评论 1 2
  • Array //声明变量arr为Array整数类型的数组,包含5个元素。 scala>valarr=newArra...
    flyskyzyl阅读 5,639评论 0 4
  • Scala的集合类可以从三个维度进行切分: 可变与不可变集合(Immutable and mutable coll...
    时待吾阅读 5,775评论 0 4
  • 浏览器内核可以分为渲染引擎和js引擎。取得网页内容,整理讯息,计算网页显示方式。所有网页浏览器、电子邮件客户端以及...
    shoutinggg阅读 443评论 0 0