From f749a51f5a7c9e2b025f4ad38ca3b004102d2685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com> Date: Mon, 6 May 2019 15:14:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E7=BB=84=E7=9B=B8=E5=85=B3=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- notes/Scala基本数据类型和运算符.md | 89 +++++++-- notes/Scala数组相关操作.md | 196 +++++++++++++++++++ notes/Scala映射和元组.md | 0 notes/Scala流程控制语句.md | 0 notes/Scala类+对象+函数.md | 0 notes/Scala集合.md | 0 6 files changed, 270 insertions(+), 15 deletions(-) create mode 100644 notes/Scala数组相关操作.md create mode 100644 notes/Scala映射和元组.md create mode 100644 notes/Scala流程控制语句.md create mode 100644 notes/Scala类+对象+函数.md create mode 100644 notes/Scala集合.md diff --git a/notes/Scala基本数据类型和运算符.md b/notes/Scala基本数据类型和运算符.md index 8145c54..c502850 100644 --- a/notes/Scala基本数据类型和运算符.md +++ b/notes/Scala基本数据类型和运算符.md @@ -3,20 +3,13 @@ - ## 一、数据类型 +### 1.1 类型支持 + Scala 拥有下表所示的数据类型,其中Byte、Short、Int、Long和Char类型统称为整数类型,整数类型加上Float和Double统称为数值类型。Scala数值类型的取值范围和Java对应类型的取值范围相同。 | 数据类型 | 描述 | @@ -36,6 +29,53 @@ Scala 拥有下表所示的数据类型,其中Byte、Short、Int、Long和Char | Any | Any是所有其他类的超类 | | AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 | +### 1.2 定义变量 + +Scala的变量分为两种,val和var,其区别如下: + ++ **val** : 类似于Java中的final变量,一旦初始化就不能被重新赋值; ++ **var** :类似于Java中的非final变量,在整个声明周期内var可以被重新赋值; + +```scala +scala> val a=1 +a: Int = 1 + +scala> a=2 +:8: error: reassignment to val // 不允许重新赋值 + +scala> var b=1 +b: Int = 1 + +scala> b=2 +b: Int = 2 +``` + +### 1.3 类型推断 + +在上面的演示中,并没有声明a是Int类型,但是程序还是把a当做Int类型,这就是Scala的类型推断。在大多数情况下,你都无需指明变量的类型,程序会自动进行推断。如果你想显式的声明类型,可以在变量后面指定,如下: + +```scala +scala> val c:String="hello scala" +c: String = hello scala +``` + +### 1.4 Scala解释器 + +在scala命令行中,如果没有对输入的值指定赋值的变量,则输入的值默认会赋值给`resX`(其中X是一个从0开始递增的整数),`res`是result的缩写,这个变量可以在后面的语句中进行引用。 + +```scala +scala> 5 +res0: Int = 5 + +scala> res0*6 +res1: Int = 30 + +scala> println(res1) +30 +``` + + + ## 二、字面量 Scala和Java字面量在使用上很多相似,比如都使用F或f表示浮点型,都使用L或l表示Long类型。下文主要介绍两者差异部分。 @@ -167,7 +207,30 @@ Int类中包含了多个重载的`+`方法,用于分别接收不同类型的
-### 3.2 运算符优先级 +### 3.2 逻辑运算符 + +和其他语言一样,在Scala中&&,||的执行是短路的,即如果左边的表达式能确定整个结果,右边的表达式就不会被执行,这满足大多数使用场景。但是如果你需要在无论什么情况下,都执行右边的表达式,则可以使用&或|代替。 + +### 3.3 赋值运算符 + +在Scala中没有Java中的`++`和`--`运算符,如果你想要实现类似的操作,只能使用`+=1`,或者`-=1`。 + +```scala +scala> var a=1 +a: Int = 1 + +scala> a+=1 + +scala> a +res8: Int = 2 + +scala> a-=1 + +scala> a +res10: Int = 1 +``` + +### 3.4 运算符优先级 操作符的优先级如下:优先级由上至下,逐级递减。 @@ -183,11 +246,7 @@ scala> 2<<(2+2) res1: Int = 32 ``` -### 3.3 逻辑运算符 - -和其他语言一样,在Scala中&&,||的执行是短路的,即如果左边的表达式能确定整个结果,右边的表达式就不会被执行,这满足大多数使用场景。但是如果你需要在无论什么情况下,都执行右边的表达式,则可以使用&或|代替。 - -### 3.4 对象相等性 +### 3.5 对象相等性 如果想要判断两个对象是否相等,可以使用`==`和`!=`,这两个操作符可以用于所有的对象,包括null。 diff --git a/notes/Scala数组相关操作.md b/notes/Scala数组相关操作.md new file mode 100644 index 0000000..3ec78eb --- /dev/null +++ b/notes/Scala数组相关操作.md @@ -0,0 +1,196 @@ +# Scala 数组相关操作 + + +## 一、定长数组 + +在Scala中,如果你需要一个长度不变的数组,可以用Array。 + +```scala +// 10个整数的数组,所有元素初始化为0 +scala> val nums=new Array[Int](10) +nums: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +// 10个元素的字符串数组,所有元素初始化为null +scala> val strings=new Array[String](10) +strings: Array[String] = Array(null, null, null, null, null, null, null, null, null, null) + +// 使用指定值初始化,此时不需要new关键字 +scala> val a=Array("hello","scala") +a: Array[String] = Array(hello, scala) + +// 使用()来访问元素 +scala> a(0) +res3: String = hello +``` + +这里需要注意以下两点: + ++ 在scala中使用`(index)`而不是`[index]`来访问数组中的元素,因为访问元素,对于Scala来说是方法调用,`(index)`相当于执行了`.apply(index)`方法。 ++ scala中的数组与Java中的是等价的,`Array[Int]()`在虚拟机层面就等价于Java的`int[]`。 + + + +## 二、变长数组 + +在scala中,通过ArrayBuffer实现变长数组(又称缓冲数组),相当于Java中的ArrayList。变长数组的构建方式及常用操作如下: + +```java +import scala.collection.mutable.ArrayBuffer + +object ScalaApp { + + // 相当于Java中的main方法 + def main(args: Array[String]): Unit = { + // 1.声明变长数组(缓冲数组) + val ab = new ArrayBuffer[Int]() + // 2.在末端增加元素 + ab += 1 + // 3.在末端添加多个元素 + ab += (2, 3, 4) + // 4.可以使用++=追加任何集合 + ab ++= Array(5, 6, 7) + // 5.缓冲数组可以直接打印查看 + println(ab) + // 6.移除最后三个元素 + ab.trimEnd(3) + // 7.在第1个元素之后插入多个新元素 + ab.insert(1, 8, 9) + // 8.从第2个元素开始,移除3个元素,不指定第二个参数的话,默认值为1 + ab.remove(2, 3) + // 9.缓冲数组转定长数组 + val abToA = ab.toArray + // 10. 定长数组打印为其hashcode值 + println(abToA) + // 11. 定长数组转缓冲数组 + val aToAb = abToA.toBuffer + } +} +``` + +这里需要说明的是:由于scala的变长数组是使用java的集合来实现的,而Java集合的底层实现是链表,这意味使用`+= `在末尾插入元素是一个高效的操作,因为其时间复杂度是O(1)。而使用insert随机插入元素的时间复杂度是O(n),因为在其插入位置之后的所有元素都要进行对应地后移,所以在`ArrayBuffer`中随机插入元素是一个低效的操作。 + +## 三、数组遍历 + +```scala +object ScalaApp extends App { + + val a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + // 1.方式一 相当于Java中的增强for循环 + for (elem <- a) { + print(elem) + } + + // 2.方式二 + for (index <- 0 until a.length) { + print(a(index)) + } + + // 3.方式三, 是第二种方式的简写 + for (index <- a.indices) { + print(a(index)) + } + + // 4.反向遍历 + for (index <- a.indices.reverse) { + print(a(index)) + } + +} +``` + +这里我们没有将代码写在main方法中,而是继承自App.scala,这是Scala提供的一种简写方式,此时将代码写在类中,等价于写在main方法中,直接运行该类即可。 + + + +## 四、数组转换 + +数组转换是指由现有数组产生新的数组。假设当前拥有a数组,想把a中的偶数元素乘以10后产生一个新的数组,可以采用下面两种方式来实现: + +```scala +object ScalaApp extends App { + + val a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + // 1.方式一 yield关键字 + val ints1 = for (elem <- a if elem % 2 == 0) yield 10 * elem + for (elem <- ints1) { + println(elem) + } + + // 2.方式二 采用函数式编程的方式,这和Java 8中的函数式编程是类似的,这里采用下划线标表示其中的每个元素 + val ints2 = a.filter(_ % 2 == 0).map(_ * 10) + for (elem <- ints1) { + println(elem) + } +} +``` + + + +## 五、多维数组 + +和Java中一样,多维数组由单位数组组成。 + +```scala +object ScalaApp extends App { + + val matrix = Array(Array(11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + Array(21, 22, 23, 24, 25, 26, 27, 28, 29, 30), + Array(31, 32, 33, 34, 35, 36, 37, 38, 39, 40)) + + + for (elem <- matrix) { + + for (elem <- elem) { + print(elem + "-") + } + println() + } + +} + +打印输出如下: +11-12-13-14-15-16-17-18-19-20- +21-22-23-24-25-26-27-28-29-30- +31-32-33-34-35-36-37-38-39-40- +``` + + + +## 六、与Java互操作 + +由于Scala的数组是使用Java的数组来实现的,所以两者之间可以相互转换。 + +```scala +import java.util + +import scala.collection.mutable.ArrayBuffer +import scala.collection.{JavaConverters, mutable} + +object ScalaApp extends App { + + val element = ArrayBuffer("hadoop", "spark", "storm") + // Scala转Java + val javaList: util.List[String] = JavaConverters.bufferAsJavaList(element) + // Java转Scala + val scalaBuffer: mutable.Buffer[String] = JavaConverters.asScalaBuffer(javaList) + for (elem <- scalaBuffer) { + println(elem) + } +} +``` + + + +## 参考资料 + +1. Martin Odersky(著),高宇翔(译) . Scala编程(第3版)[M] . 电子工业出版社 . 2018-1-1 +2. 凯.S.霍斯特曼(著),高宇翔(译) . 快学Scala(第2版)[M] . 电子工业出版社 . 2017-7 \ No newline at end of file diff --git a/notes/Scala映射和元组.md b/notes/Scala映射和元组.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/Scala流程控制语句.md b/notes/Scala流程控制语句.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/Scala类+对象+函数.md b/notes/Scala类+对象+函数.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/Scala集合.md b/notes/Scala集合.md new file mode 100644 index 0000000..e69de29