天天看点

Scala基础Scala基础

Scala基础

Scala是一门类似Java的多范式语言,集合了面向对象编程和函数式编程的特性。

使用Scala语言编写Spark应用程序的考虑:

1)Scala具有强大的并发性,支持函数式编程,可以更好的支持分布式系统。在大数据时代,为了提高应用程序的并发性,函数式编程日益收到关注;

2)Scala兼容Java,可以与Java互操作。Scala代码文件会被编译成Java的class文件,开发者可以从Scala中调用Java类库;

3)Scala代码简洁优雅;

4)Scala支持高效的交互式编程。其提供了交互式解释器(Read-Eval-Print Loop, REPL),因此在Spark-shell中可进行交互式编程。

5)Scala是Spark的开发语言。用Scala语言编写Spark应用程序可以获得最好的执行性能。

基本数据类型

1、Scala的数据类型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean(注意首字母大写)

2、和Java不同的是,在Scala中,这些类型都是"类",并且都是包scala的成员,比如,Int的全名是scala.Int。对于字符串Scala用java.lang.String类来表示字符串

Scala基础Scala基础

除了以上9种基本类型,Scala还提供了一个Unit类型,类似Java中的void类型。

字面量

val i=123//123就是整数字面量
val i=3.14//3.14就是浮点数字面量
val i=true//true就是布尔型字面量
val i='A'//'A'就是字符字面量
val i="Hello"//"Hello"就是字符串字面量
           

基本操作

• 算术运算符:加(+)、减(-) 、乘(*) 、除(/) 、余数(%);

• 关系运算符:大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=)

• 逻辑运算符:逻辑与(&&)、逻辑或(||)、逻辑非(!);

• 位运算符:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)等

• 赋值运算符:=及其与其它运算符结合的扩展赋值运算符,例如+=、%=。

• 操作符优先级:算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符

变量

Scala有两种类型的变量

1)val:是不可变的,在声明时就必须被初始化,而且初始化以后就不能再赋值。

2)var:是可变的,声明的时候需要进行初始化,初始化以后还可以再次对其赋值。

基本语法:

val 变量名:数据类型 = 初始值

var 变量名:数据类型 = 初始值

但是,Scala有类型推断机制

Scala基础Scala基础

输入和输出

控制台输入输出

从控制台读取数据

• 从控制台读取数据方法:readInt、readDouble、readByte、readShort、readFloat、readLong、readChar readBoolean及readLine,分别对应9种基本数据类型,其中前8种方法没有参数,readLine可以不提供参数,也可以带一个字符串参数的提示

• 所有这些函数都属于对象scala.io.StdIn的方法,使用前必须导入,或者直接用全称进行调用

Scala基础Scala基础

向控制台输出信息方法

• print()和println(),可以直接输出字符串或者其它数据类型,其中println在末尾自动换行。

也有printf函数

s字符串和f字符串:Scala提供的字符串插值机制,以方便在字符串字面量中直接嵌入变量的值。

基本语法:

s " …$变量名… "

f " …$变量名%格式化字符… "

Scala基础Scala基础

读写文件

写入文件

• Scala需要使用java.io.PrintWriter实现把数据写入到文件,PrintWriter类提供了print 和println两个写方法

Scala基础Scala基础
Scala基础Scala基础

读取文件

• 可以使用Scala.io.Source的getLines方法实现对文件中所有行的读取

Scala基础Scala基础

控制结构

if条件表达式

和java类似

package cn.itcast.scala

object test {
  def main(args: Array[String]) {
    val x=3
    if(x>0){
      println("this is a positive number")
    }else if(x==0){
      println("this is a zero")
    }else{
      println("this is a negetive number")
    }
  }
}
           
Scala基础Scala基础

有一点与Java不同的是,Scala中的if表达式的值可以赋值给变量

Scala基础Scala基础

while循环

与Java完全相同

package cn.itcast.scala

object test {
  def main(args: Array[String]) {
    var i=9
    while (i>0){
      i-=1
      printf("i is %d\n",i)
    }
  }
}
           
Scala基础Scala基础
package cn.itcast.scala

object test {
  def main(args: Array[String]) {
    var i=0
    do{
      i+=1
      println(i)
    }while(i<5)
  }
}
           
Scala基础Scala基础

for循环

与Java的for循环相比,Scala的for循环在语法表示上有较大的区别,同时,for也不是while循环的一个替代者,而是提供了各种容器遍历的强大功能。

基本结构:

for (变量 <- 表达式) {语句块}

其中,

“变量<-表达式”

被称为“生成器(generator)”

for(i<- 1 to 5)
  println(i)
for (j <- 1 to 10 by 2)
  println(j)
           

此处,变量不需要关键字var或val进行声明。

1 to 10为一个整数的Range型容器,包含1到10.

守卫(guard)

“守卫(guard)”的表达式:过滤出一些满足条件的结果。基本语法:

for (变量 <- 表达式 if 条件表达式)

语句块

for (i <- 1 to 5 if i%2==0)
  println(i)
           

上述语句等价于:

for (i<- 1 to 5)
	if (i%2==0)
		println(i)
           

注意:如果需要多个多虑条件,可以增加多个if语句,并用分号隔开。

Scala也支持“多个生成器”的情形,可以用分号把它们隔开,比如:

for(i <- 1 to 5;j <- 1 to 3)
  println(i*j)
           
Scala基础Scala基础

可以看出实际上实现了循环嵌套

For推导式

• for结构可以在每次执行的时候创造一个值,然后将包含了所有产生值的集合作为for循环表达式的结果返回,集合的类型由生成器中的集合类型确定。

for (变量 <- 表达式) yield {语句块}

Scala基础Scala基础

对循环的控制

为了提前终止整个循环或者跳到下一个循环,Scala没有break和continue关键字。Scala提供了一个Breaks类(位于包scala.util.control)。Breaks类有两个方法用于对循环结构进行控制,即breakable和break:

将需要控制的语句块作为参数放在breakable后面,然后,其内部在某个条件满足时调用break方法,程序将跳出breakable方法。

Scala基础Scala基础

数据结构

数组Array,元组Tuple,列表List,映射Map,集合Set

数组

数组:一种可变的、可索引的、元素具有相同类型的数据集合。

Scala提供了参数化类型的通用数组类Array[T],其中T可以是任意的Scala类型,可以通过显式指定类型或者通过隐式推断来实例化一个数组。

Scala基础Scala基础
Scala基础Scala基础

可以发现,没有使用new来生成对象,实际上是因为使用了Scala中的伴生对象的apply方法。

多维数组的创建:调用Array的ofDim方法

val  myMatrix = Array.ofDim[Int](3,4)  //类型实际就是Array[Array[Int]]
val  myCube = Array.ofDim[String](3,2,4)  //类型实际是Array[Array[Array[String]]]
           

可以使用多级圆括号来访问多维数组的元素,例如

myMatrix(0)(1)

返回第一行第二列的元素

元组

元组是对多个不同类型对象的一种简单封装。定义元组最简单的方法就是把多个元素用逗号分开并用圆括号包围起来。

使用下划线“_”加上从1开始的索引值,来访问元组的元素。

val tuple =("BigData",2021,8.24)
println(tuple._1) //返回BigData
           

如果需要在方法里返回多个不同类型的对象,Scala可以通过返回一个元组实现。

val (t1,t2,t3)=tuple
print(t1) //返回BigData
print(t2)
print(t3)
           

容器

Scala提供了一套丰富的容器(collection)库,包括序列(Sequence)、集合(Set)、映射(Map)等。

• Scala用了三个包来组织容器类,分别是scala.collection 、scala.collection.mutable和scala.collection.immutable。scala.collection包中的容器通常都具备对应的不可变实现和可变实现。

scala.collection包中容器的宏观层次结构:

Scala基础Scala基础

序列

序列(Sequence): 元素可以按照特定的顺序访问的容器。序列中每个元素均带有一个从0开始计数的固定索引位置。

两种常用的序列:列表List和Range

(1)列表

• 列表: 一种共享相同类型的不可变的对象序列。定义在

scala.collection.immutable

包中

• 不同于Java的

java.util.List

,scala的List一旦被定义,其值就不能改变,因此声明List时必须初始化

• 列表有头部和尾部的概念,可以分别使用head和tail方法来获取

• head返回的是列表第一个元素的值

• tail返回的是除第一个元素外的其它值构成的新列表,这体现出列表具有递归的链表结构

strList.head

将返回字符串”BigData”,

strList.tail

返回

List ("Hadoop","Spark")

• 构造列表常用的方法是通过在已有列表前端增加元素,使用的操作符为

::

,例如:

val otherList="Apache"::strList

(2)Range

Range类:一种特殊的、带索引的不可变数字等差序列。其包含的值为从给定起点按一定步长增长(减小)到指定终点的所有数值。

Scala基础Scala基础
Scala基础Scala基础
Scala基础Scala基础

集合set

• 不重复元素的容器(collection)。

• 列表中的元素是按照插入的先后顺序来组织的,但是,“集合”中的元素并不会记录元素的插入顺序,而是以“哈希”方法对元素的值进行组织,所以,它允许你快速地找到某个元素

• 集合包括可变集和不可变集,分别位于

scala.collection.mutable

包和

scala.collection.immutable

包,缺省情况下创建的是不可变集

var mySet = Set("Hadoop","Spark")
mySet += "Scala" 
           

如果要声明一个可变集,则需要提前引入scala.collection.mutable.Set

import scala.collection.mutable.Set
val myMutableSet = Set("Database","BigData")
myMutableSet += "Cloud Computing" 
           

映射Map

• 映射(Map):一系列键值对的容器。键是唯一的,但值不一定是唯一的。可以根据键来对值进行快速的检索

• Scala 的映射包含了可变的和不可变的两种版本,分别定义在包

scala.collection.mutable

scala.collection.immutable

里。默认情况下,Scala中使用不可变的映射。如果想使用可变映射,必须明确地导入

scala.collection.mutable.Map

如果要获取映射中的值,可以通过键来获取

Scala基础Scala基础

对于这种访问方式,如果给定的键不存在,则会抛出异常,为此,访问前可以先调用contains方法确定键是否存在

Scala基础Scala基础

迭代器Iterator

• 迭代器(Iterator)不是一个容器,而是提供了按顺序访问容器元素的数据结构。

• 迭代器包含两个基本操作:next和hasNext。next可以返回迭代器的下一个元素,hasNext用于检测是否还有下一个元素

Scala基础Scala基础