由于学习Spark需要用到Scala,这里简单记录一下Scala的一些基础语法。
1 变量类型
- val,是不可变的,在声明时就必须被初始化,而且初始化以后就不能再赋值
- var,是可变的,声明的时候需要进行初始化,初始化以后还可以再次对其赋值。
2 基本数据类型
包括Byte、Char、Short、Int、Long、Float、Double和Boolean。
和Java不同的是,在Scala中,这些类型都是“类”
。
3 字面量
包括整数字面量、浮点数字面量、布尔型字面量、字符字面量、字符串字面量、符号字面量、函数字面量和元组字面量。
字面量可以理解为赋给变量的值
。
Scala允许对“字面量”直接执行方法
。例如:
5.toString() //产生字符串"5"
"abc".intersect("bcd") //输出"bc"
4 操作符
在Scala中,可以使用加(+)、减(-) 、乘(*) 、除(/) 、余数(%)等操作符,而且,这些操作符就是方法。例如,5 + 3
和(5).+(3)
是等价的。即a 方法 b
与a.方法(b)
是等价的。
Scala中并没有提供++和–操作符,用+=和-=代替即可。
5 Range 和 for 循环
在创建Range时,需要给出区间的起点和终点以及步长(默认步长为1)。
1 to 5 // 创建一个从1到5的数值序列,包含区间终点5,步长为1
1 until 5 // 创建一个从1到5的数值序列,不包含区间终点5,步长为1
1 to 10 by 2 // 创建一个从1到10的数值序列,包含区间终点10,步长为2
在执行for循环时,我们经常会用到数值序列,比如,i的值从1循环到5,这时就可以采用Range来实现。
Scala中的for循环语句格式如下:for (变量<-表达式) 语句块
其中,“变量<-表达式”被称为“生成器(generator)”
for (i <- 1 to 5) println(i)
for (i <- 1 to 5 if i%2==0) println(i)
有时候,我们可能希望过滤出一些满足制定条件的结果,这个时候就需要使用到称为“守卫(guard)”的表达式。
for (i <- 1 to 5 if i%2==0) println(i) // 输出1到5之中的所有偶数
Scala也支持“多个生成器”的情形,可以用分号把它们隔开(可以理解为嵌套循环)
for (i <- 1 to 5; j <- 1 to 3) println(i*j)
6 打印语句
print("Hello world!"); // 不换行打印
print("Hello world!"); // 换行打印
printf("My name is %s. I hava %d apples and %d eggs.\n","scala",i,j) // 格式化打印(与C语语言类似)
val name = "小明"
print(s"我是$name $$") // 输出:我是小明 $
7 数组(array)
一般包括定长数组(长度不变)和变长数组(长度可变)
val intValueArr = new Array[Int](3) //声明一个长度为3的整型数组,每个数组元素初始化为0
intValueArr(0) = 12 //给第1个数组元素赋值为12
intValueArr(1) = 45 //给第2个数组元素赋值为45
intValueArr(2) = 33 //给第3个数组元素赋值为33
在Scala中,对数组元素的引用,是使用圆括号,而不是方括号。
Scala提供了更加简洁的数组声明和初始化方法。
val intValueArr = Array(12,45,33) // 自动根据提供的初始化数据来推断出数组的类型
8 列表(list)
列表有头部和尾部的概念,可以使用intList.head来获取上面定义的列表的头部,值是1,使用intList.tail来获取上面定义的列表的尾部,值是List(2,3),可以看出,头部是一个元素,而尾部则仍然是一个列表。
由于列表的头部是一个元素,所以我们可以使用::操作,在列表的头部增加新的元素,原列表不变,返回新列表。
val intList = List(1,2,3) // 声明一个列表
val intListOther = 0::intList
::操作符是右结合的,因此,如果要构建一个列表List(1,2,3),实际上也可以采用下面的方式:
val intList = 1::2::3::Nil // Nil表示空列表
我们也可以使用:::操作符对不同的列表进行连接得到新的列表
val intList1 = List(1,2)
val intList2 = List(3,4)
val intList3 = intList1:::intList2
9 元组(tuple)
元组是不同类型的值的聚集
。元组和列表不同,列表中各个元素必须是相同类型,而元组可以包含不同类型的元素。
val tuple = ("BigData",2015,45.0) // 声明一个元组(用圆括号把多个元组的元素包围起来即可)
// 访问元组中的某个元素的值,tuple._1、tuple._2、tuple._3
println(tuple._1)
println(tuple._2)
println(tuple._3)
10 集(Set)
集(set)是不重复元素的集合
。列表中的元素是按照插入的先后顺序来组织的,但是,”集”中的元素并不会记录元素的插入顺序,而是以“哈希”方法对元素的值进行组织,所以,它允许你快速地找到某个元素。
集包括可变集和不可变集,缺省情况下创建的是不可变集,通常我们使用不可变集。
如果要声明一个可变集,则需要引入scala.collection.mutable.Set
包。
虽然可变集和不可变集都有添加或删除元素的操作,但是二者有很大的区别。对不可变集进行操作,会产生一个新的集,原来的集并不会发生变化。 而对可变集进行操作,改变的是该集本身。
11 映射(map)
映射(Map)是一系列键值对的集合
映射包括可变和不可变两种,默认情况下创建的是不可变映射,如果需要创建可变映射,需要引入scala.collection.mutable.Map
包。
// 声明不可变映射
val university = Map("NEU" -> "Northeastern University", "THU" -> "Tsinghua University","PKU"->"Peking University")
// 通过键获取键值对的值
println(university("NEU"))
// 使用contains方法检查映射中是否包含某个值
println(if (university.contains("NEU")) university("NEU") else 0)
上面我们定义的是不可变映射,是无法更新映射中的元素的,也无法增加新的元素。如果要更新映射的元素,就需要定义一个可变的映射
import scala.collection.mutable.Map
val university2 = Map("NEU" -> "Northeastern University", "THU" -> "Tsinghua University","PKU"->"Peking University")
university2("NEU") = "Northeastern University " //更新已有元素的值
university2("FZU") = "Fuzhou University" //添加新元素
// 也可以使用+=操作来添加新的元素
university2 += ("TJU"->"Tianjin University") //添加一个新元素
university2 += ("SDU"->"Shandong University","WHU"->"Wuhan University") //同时添加两个新元素
循环遍历映射
for ((k,v) <- university) printf("Code is : %s and name is: %s\n",k,v) // 遍历键值对
for (k<-university.keys) println(k) // 遍历键
for (v<-university.values) println(v) // 遍历值
12 读写文件
Scala需要使用java.io.PrintWriter实现把数据写入到文本文件。
import java.io.PrintWriter
val out = new PrintWriter("output.txt")
for (i <- 1 to 5) out.println(i)
out.close()
可以使用scala.io.Source的getLines方法实现对文件中所有行的读取
import scala.io.Source
val inputFile = Source.fromFile("output.txt")
val lines = inputFile.getLines
for (line <- lines) println(line)