关于Scala
-
Scala是在Java的基础上开发而成,运行于Java虚拟机
-
Scala的语法结构类似于Java和python的结合
- 如果一行只有一行语句,行尾可以不用加分号
- 与Java不同,Scala可以在类外单独定义全局函数
-
Scala中没有static关键字
-
Scala以object类中的main函数作为程序入口,如:
object HelloWorld{ def main(args:Array[String]):Unit={ println("hello world") } }
数据类型
- Scala提供以下基础数据类型:
- Int
- Float
- Double
- String
- Boolean
- Unit:表示无值,同Java的void,用作不返回任何结果的方法的结果类型
- 同python,Scala中数据类型均是对象
- Scala拥有垃圾回收机制
常量和变量
常量
-
Scala定义常量使用 val 关键字,定义格式:
val name[:type]=initialization
-
中括号中为可选项,如:
val v1 : Int = 5 val v2 = 6 // <==> val v2 : Int = 6
-
变量
-
Scala中定义变量使用 var 关键字,定义格式:
var name[:type]=initialization
-
与定义常量类似,中括号中为可选项,如:
var v : Int = 5 var vv = 10 // <==> var vv : Int = 10
-
命名规范
- Scala中变量与常量要求以
字母
或下划线
开头,后面跟着更多的字母、数字、下划线
运算符
- 算数运算符:
+
-
*
/
%
- 关系运算符:
>
<
>=
<=
==
!=
- 逻辑运算符:
&&
||
!
- 位运算符:
&
|
^
- 赋值运算符:
=
+=
-=
*=
/=
%=
<<=
>>=
&=
|=
^=
- Scala中运算符的调用格式有两种,一种是常见的如同
a + b
,另一种是a .+(b)
- 即表示为
a .运算符(b)
- 即表示为
容器
数组 Array
-
数组是一种存储了相同类型元素的固定大小的顺序集合
-
Scala中声明数组中的语法如下:
-
var arr:Array[String] = new Array[String](length)
-
var arr = Array(elem1, emem2, …)
-
如,声明一个不可变数组,长度为3,并赋值
val arr:Array[String] = new Array[String](3) arr(0) = "this"; arr(1) = "that"; arr(2) = "there"; // Scala数组使用()通过下标访问元素 val arr2 = Array("this", "that", "there")
-
也可以使用range()方法创建等差数组,该方法需要 import Array._
import Array._ var arr = range(1,10,2) // range同python
-
-
数组的常用方法:
- arr.length 返回数组的长度
- arr.head 查看数组的第一个元素
- arr.tail 查看数组中除了第一个元素外的其他元素
- arr.isEmpty 判断数组是否为空
- arr.contains(x) 判断数组中是否包含元素x
- 注:Scala中调用类方法如果没有参数,必须省略括号
- 如 arr.head() 必须写为 arr.head
-
连接两个数组可以使用操作符 ++ ,也可以使用函数 concat()
-
使用 concat 方法前需要使用 import Array._ 先引入包
var arr1 = Array(1,2,3) var arr2 = Array(4,5,6) var arr3 = arr1 ++ arr2 import Array._ var arr4 = concat(arr1, arr2)
-
-
Scala默认创建的是不可变数组
-
这里的不可变指的是数组本身不可变,即不可指向其他数组,内部的元素依然可以更改
-
创建可变数组需要导入包 import scala.collection.mutable.ArrayBuffer
-
列表 List
-
列表的所有元素都具有相同的类型
-
与数组不同的是列表的元素也都是不可变的
-
列表的声明语法如下
-
var lis : List[type] = List(elem1,elem2,…)
val lis : List[String] = List("this","that","there") val lsi2 : List[Int] = List(1,2,3,4) val lis3 : List[Nothing] = List()
-
var lis : List[type] = elem1 :: elem2 :: … :: Nil
-
::和Nil是构造列表的两个基本单位,Nil表示空列表,::为中缀操作符,表示列表从前端扩展,遵循右结合
val lis : List[String] = "this" :: "that" :: "there" :: Nil val lis2 : List[Int] = 1 :: 2 :: 3 :: Nil val lis3 : List[Nothing] = Nil
-
-
列表的常用方法:
- lis.head 获取第一个元素
- lis.init 返回所有元素,除了最后一个
- lis.last 获取最后一个元素
- lis.tail 返回除了第一个的所有元素
- lis.:::(prefix:List[A]) 在列表开头添加指定列表的元素
- 用于合并两个列表,如
lis1:::lis2
或lis1.:::(lis2)
- 也可用concat方法,如
List.concat(lis1, lis2)
- 用于合并两个列表,如
- lis.take(n:Int) 获取列表的前n个
- lis.contains(x) 判断元素x是否在列表中
集合 Set
-
与列表相比,集合中的所有元素都是唯一的。
-
集合的声明方式如下
-
val st : Set[type] = Set(elem1, elem2, ...)
val sst : Set[Int] = Set(1,2,3,4,5,5,5)
-
-
集合的常用方法:
- st.head 获取第一个元素
- st.init 返回所有元素,除了最后一个
- st.last 返回最后一个元素
- st.tail 返回所有元素,除了第一个
- st.++(elems:Set[A]) 合并两个集合
- 同数组,不同于列表
- st.take(n:Int) 获取列表前n个元素
- st.contains(x:A) 判断x是否在集合中
-
Scala默认是创建不可变集合
- 创建可变集合需要导入包 import scala.collection.mutable.Set
映射 Map
-
映射是一种可迭代的键值对结构,所有值都可以通过键来获取,且键值唯一
-
声明映射的语法如下:
-
val mp : Map[type1,type2] = Map(key1->value1,key2->value2,…)
val person : Map[String,Int] = Map("jhon"->34,"joe"->22)
-
-
映射的常用方法:
- 集合的常用方法基本于映射相同,这里列举不同的方法
- mp.isEmpty 判断映射是否为空
- mp.keys 返回所有的键
- mp.values 返回所有的值
元组 Tuplen
-
元组是一种类似于列表的结构,但与列表不同的是,元组可以包含不同类型的元素,元组的值是通过将单个的值包含在圆括号中构成的
-
元组的声明语法如下
-
val tp = TupleN(elem1,elem2,elem3)
- 这里的Tuple为元组关键字,N为指定元组的长度
-
val tp = (elem1, elem2, elem3)
- 这里的elem1,elem2,elem3属于不同类型
val tp1 = Tuple3(1, 3.14, "this") // 三元组 val tp2 = (1, 3.14, "this") // 同上 var tp3 = Tuple4("that", 1, 2.5, "this") // 四元组
-
-
Scala中元组的最大长度为22,即最多可包含22个元素
-
访问元组可以通过 元组名称._元素索引,索引从1开始
val tp = Tuple3(1, 3.14, "this") tp._1 // 访问第一个元素 1 tp._2 // 访问第二个元素 3.14 tp._3 // 访问第三个元素 "this"
if分支
- if
- if(condition){…}
- if…else
- if(condition){…}
- else {…}
- if…else if…else
- if(condition){…}
- else if (condition) {…}
- else {…}
- if…>if
- if(condition){if(condition){}}
循环
-
while
-
example:
var n = 5 while(n > 0){ n -= 1 }
-
-
do…while
-
example:
var n = 5 do{ n -= 1 }while(n >= 0)
-
-
for
-
for (variable <- Set) {...}
- Set could be:
- a to b // include b
- a until b // do not include b
- st // st is a Set
- Set could be:
-
example:
for (var i <- 1 to 10){ println(i) } for (var i <- 1 until 10){ println(i) } var st : Set[Int] = Set(1,3,5,7,9) for (var i <- st){ println(i) }
-
-
multiple for
-
for (v1 <- Set1 ; v2 <- Set2){...}
- <==> for (v1 <- Set1){ for (v2 <- Set2) {…} }
-
example:
for (var i <- 1 to 10; var j <- 1 to i){ print(i*j) } // equivalent to below: for (var i <- 1 to 10){ for (var j <- 1 to i){ print(i*j) } }
-
函数
普通函数
-
definition:
-
def funName(para1:type1,para2:type2,...)[:returnType]={...}
-
example:
def fun1(a:Int, b:Int):Unit={ print(a + b) } def fun2(a:Int, b:Int):Int={ return a + b } def fun3(a:Int, b:Int)={ return a + b } // fun3 is equivalent to below def fun4(a:Int, b:Int)={a + b} // 'return' could be ignored
-
匿名函数
-
定义:
-
匿名函数使用
=>
进行定义 -
(para1:type1,para2:type2,...)=>functionBody
-
如:
(x:Int, y:Int) => x + y g = (x:Int, y:Int) => x + y
-
匿名函数也可以使用
_
进行定义 -
如:
val add = (_:Int) + (_:Int)
- 使用该方法定义匿名函数时应当确保每个参数仅使用一次
-
函数作为参数的函数
1.函数作为参数的函数与一般函数的定义方式相同, 但至少拥有一个函数形式的形参.
-
如:
def fun(f:(Int,Int)=>Int,a:Int,b:Int):Unit={ fun(a,b) } // call the function like val g = (x:Int, y:Int) => a+b fun(g, 1, 2)
函数作为返回值的函数
-
函数作为返回值的函数与一般函数的定义方式相同,但它的返回值是另一个函数。
-
如:
def fun(x:Int)={ return (y:Int)=>x+y } // call the function like val g = fun(5) g(10)
函数柯里化
-
函数柯里化是指将一次调用多个参数的函数拆分成多次调用一个参数的函数
-
如:
def add(x:Int, y:Int):Int={return a+b} // 柯里化定义为 def add2(x:Int)(y:Int):Int={return a+b}
函数组合器
-
map
-
map是一个函数,用于从序列中取出每一个元素,并通过自定义函数加以处理后,返回一个新的序列,新序列的元素个数与原来相同
-
scala中, map作为一个类方法
-
map操作不会影响原始数据
-
如:
val num : List[Int] = List(1,2,3,4,5) num.map((x:Int)=>x*2) // will get List(2,4,6,8,10)
-
-
foreach
-
同map一样,但foreach没有返回值,仅仅将序列中所有的元素从依次取出进行处理。
-
同样,foreach也作为一个类方法
-
foreach也不会影响原始数据
-
如:
val num : List[Int] = List(1,2,3,4,5) num.foreach((x:Int)=>x*2) // will get nothing num.foreach((x:Int)=>print(x*2)) // will display 2 4 6 8 10
-
-
filter
-
filter 需要一个返回布尔类型的函数作为参数,将序列中的所有元素依次取出放入函数进行判断,仅保留返回值为true的元素构成的序列.
-
filter 将会影响原始数据
-
如:
val num : List[Int] = List(1,2,3,4,5) num.filter(x=>x%2==0) // remove odd number // num will be List(2,4)
-
-
flatten
-
flatten 用于扁平化序列,将高维序列扁平化为1维。
-
flatten 将会影响原始数据
-
如:
val lis = List(List(1,2,3),List(4,5)) list.flatten // lis will be List(1,2,3,4,5)
-
-
flatMap
-
flatMap 是flat和map的结合操作. 它接收一个处理嵌套序列的函数作为参数, 同时, 返回一个经由函数处理后的元素组合而成的1维序列.
-
flatMap 将会影响原始数据
-
如:
val num = List(List(1,2,3),List(4,5)) num.flatMap(x=>x.map(_*2)) // num will be List(2,4,6,8,10) // is like below num = num.map(x=>x*2) num.flatten
-
-
groupBy
-
groupBy 接收一个返回布尔类型的函数作为参数, 对序列所有元素通过该函数进行分组, 返回值为Map类型
-
groupBy 不会影响原始数据
-
如:
val num : List[Int] = List(1,2,3,4,5,6) num.groupBy(x=>x%2==0) // will get Map(false->List(1,3,5),true->(2,4,6))
-
类和对象
类定义
-
使用class关键字定义类,语法如下
- class className[(para1, para2,…)][extends base]{…}
-
类可以有参数,用于类成员的初始化
-
类使用extends关键字继承
- 同Java,Scala仅支持继承一个父类
- 子类覆盖父类已经实现的方法需要override关键字
- 子类覆盖父类未实现的抽象方法不用override关键字
- 同Java,抽象类使用关键字abstract
-
如:
abstract class Base{ def sayhello:Unit={ println("hello") } def saysome(some:String) : Unit; } class MyClass(x:Int, y:Int)extends Base{ var xl:Int = x var yl:Int = y override def sayhello:Unit={ println("HELLO!") } def saysome(some:String) : Unit = { println(some) } }
单例类
-
Scala中没有static关键字,故此不存在静态成员,Scala使用object类实现单例模式
-
使用object定义一个单例对象,在整个程序中只有这么一个实例,object对象不能携带参数
-
定义语法如下
- object objectName{…}
-
object对象中的main函数将作为程序的入口
-
当object与同一个文件中的class同名时,object称为class的伴生对象,class称为object的伴生类,互相可以访问私有成员
-
如
object MyClass{ def main(args:Array[String]):Unit={ println(MyClass.info) } } class MyClass{ private val info:String = "this" }
Scala模式匹配
-
Scala模式匹配机制通过一个特殊的函数定义,通过传入的参数匹配到不同的执行方案,如Java中的switch
-
如
def matchTest(X:Int) = x match { case 1 => println("one") case 2 => println("two") case _ => println("other") }
-
模式匹配中每个case不需要break,匹配到case执行后自动结束,Scala中也没有break关键字
-
模式匹配也可用于列表,可网上查询
文件读写
名时,object称为class的伴生对象,class称为object的伴生类,互相可以访问私有成员
-
如
object MyClass{ def main(args:Array[String]):Unit={ println(MyClass.info) } } class MyClass{ private val info:String = "this" }
Scala模式匹配
-
Scala模式匹配机制通过一个特殊的函数定义,通过传入的参数匹配到不同的执行方案,如Java中的switch
-
如
def matchTest(X:Int) = x match { case 1 => println("one") case 2 => println("two") case _ => println("other") }
-
模式匹配中每个case不需要break,匹配到case执行后自动结束,Scala中也没有break关键字
-
模式匹配也可用于列表,可网上查询