Spark02-Scala编程基础

本篇博客主要了解基础重要的Scala语法,为 spark 的学习打下基础。

1、基本语法

1.1 声明值和变量

Scala有两种类型的变量:

  • val: 是不可变的,在声明时就必须被初始化,而且初始化以后就不能再赋值;
  • var: 是可变的,声明的时候需要进行初始化,初始化以后还可以再次对其赋值。

1.2 基本数据类型和操作

  • Scala的数据类型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean
  • 和Java不同的是,在Scala中,这些类型都是“类”,并且都是包scala的成员,比如,Int的全名是scala.Int。对于字符串,Scala用java.lang.String类来表示字符串

操作符:在Scala中,可以使用加(+)、减(-)、乘(*)、除(/)、余数(%)等操作符,而且,这些操作符就是方法。例如,5+3和(5).+(3)是等价的,也就是说:

a 方法 b 等价于 a.方法(b)

前者是后者的简写形式,这里的+是方法名,是Int类中的一个方法。 

需要注意的是:和Java不同,在Scala中没有提供递增 递减 ++, -- 操作符,可以使用 += 、-= 方式进行表达

富包装类

  • ·对于基本数据类型,除了以上提到的各种操作符外,Scala还提供了许多常用运算的方法,只是这些方法不是在基本类里面定义,还是被封装到一个对应的富包装类中
  • 每个基本类型都有一个对应的富包装类,例如 Int 有一个 RichInt 类、String 有一个 RichString 类,这些类位于包 scala.runtime 中
  • ·当对一个基本数据类型的对象调用其富包装类提供的方法,Scala会自动通过隐式转换将该对象转换为对应的富包装类型,然后再调用相应的方法。例如: 3 max 5

1.3 Range

  • 在执行for循坏时,我们经常会用到数值序列,比如,i 的值从1循环到5,这时就可以采用 Range 来实现
  • Range可以支持创建不同数据类型的数值序列,包括 Int、Long、Float、Double、Char、BigInt 和 BigDecimal 等

举例说明:

(1)创建一个从1到5的数值序列,包含区间终点5,步长为1

(2)创建一个从1到5的数值序列,不包含区间终点5,步长为1

(3)创建一个从1到10的数值序列,包含区间终点10,步长为2

(4)创建一个Float类型的数值序列,从0.5f到5.9f,步长为0.3f

1.4 控制台输入输出语句

  • 为了从控制台读写数据,可以使用以read为前缀的方法,包括: readInt、readDouble、readByte、readShort、readFloat、readLong、readChar readBoolean及readLine,分别对应9种基本数据类型,其中前8种方法没有参数,readLine可以不提供参数,也可以带一个字符串参数的提示
  • 所有这些函数都属于对象scala.io.StdIn的方法,使用前必须导入,或者直接用全称进行调用

为了向控制台输出信息,常用的两个函数是 print()和println() , 可以直接输出字符串或者其它数据类型

Scala还带有C语言风格的格式化字符串的printf()函数

print()、println() 和 printf() 都在对象 Predef 中定义,该对象默认情况下被所有 Scala 程序引用,因此可以直接使用 Predef 对象提供的方法,而无需使用 scala.Predef. 的形式

1.5 读写文件

写入文件

Scala需要使用 java.io.PrintWriter 实现把数据写入到文件。

如果我们想把文件保存到一个指定的目录下,就需要给出文件路径

 读取文件

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

1.6 异常处理

2、控制结构

2.1 if 条件表达式

基本使用与Java一样,但有一点与Java不同的是,Scala 中的 if 表达式的值可以赋值给变量。

2.2 while 循环

和 Java 语法一样,分为 while 和 do while。

2.3 for 循环

Scala中的for循环语句格式如下:for ( 变量 <- 表达式 ) 语句块

其中,“变量<-表达式”被称为“生成器(generator)”

  • 不希望打印出所有的结果,过滤出一些满足制定条件的结果,需要使用到称为“守卫(guard)”的表达式
  • 比如,只输出1到5之中的所有偶数,可以采用以下语句:

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

可以给每个生成器都添加一个“守卫”,如下:

 for 推导

  •  Scala的 for 结构可以在每次执行的时候创造一个值,然后将包含了所有产生值的集合作为for循环表达式的结果返回,集合的类型由生成器中的集合类型确定
  • 通过 for 循环遍历一个或多个集合,对集合中的元素进行“推导”,从而计算得到新的集合,用于后续的其他处理

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

 3、数据结构

3.1容器(Collection)

  • Scala提供了一套丰富的容器(collection)库,包括列表(List)、数组(Array)、集合( Set)、映射(Map)等
  • 根据容器中元素的组织方式和操作方式,可以区分为 有序 和 无序、可变 和 不可变 等不同的容器类别
  • Scala用了三个包来组织容器类,分别是scala.collection 、scala.collection.mutable 和 scala.collection.immutable

下图显示了scala.collection包中所有的容器类。这些都是高级抽象类或特质。例如,所有容器类的基本特质(trait)是Traverable特质,它为所有的容器类定义了公用的foreach方法,用于对容器元素进行遍历操作

下面的图表显示了scala.collection.immutable中的所有容器类

下面的图表显示scala.collection.mutable中的所有容器类

3.2列表(List)

  • 列表是一种共享相同类型的不可变的对象序列。既然是一个不可变的集合,Scala的List定义在scala.collection.immutable包中
  • 不同于Java的java.util.List,scala的List一旦被定义,其值就不能改变,因此声叨List时必须初始化
    • var strList=List("BigData","Hadoop","Spark")
  • 列表有头部和尾部的概念,可以分别使用head和tail方法来获取
    • head返回的是列表第一个元素的值
    • tail返回的是除第一个元素外的其它值构成的新列表,这体现出列表具有递归的链表结构
  • strList.head将返回字符串”BigData”,strList.tail返回List("Hadoop","Spark")

构造列表常用的方法是通过在已有列表前端增加元素,使用的操作符为 ::  ,例如:
  val otherList = "Apache" :: strList
执行该语句后strList保持不变,而otherList将成为一个新的列表:
  List("Apache","BigData","Hadoop","Spark")
Scala还定义了一个空列表对象Nil,借助Nil,可以将多个元素用操作符 :: 串起来初始化一个列表
  val intList = 1::2::3::Nil 与val intList = List(1,2,3)等效

3.3集合(Set)

    • 集合(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"

3.4映射(Map)

  • 映射(Map)是一系列键值对的容器。在一个映射中,键是唯一的,但值不一定是唯一的。可以根据键来对值进行快速的检索
  • 和集合一样,Scala采用了类继承机制提供了可变的和不可变的两种版本的映射,分别定义在包scala.collection.mutable和scala.collection.immutable 里。默认情况下,Scala中使用不可变的映射。如果想使用可变映射,必须明确地导入scala.collection.mutable.Map

    val university = Map("XMU" -> "Xiamen University","THU" ->"Tsinghua University", "PKU"->"PekingUniversity")

获取值:university("XMU")

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

不可变映射,是无法更新映射中的元素的,也无法增加新的元素。如果要更新映射的元素,就需要定义一个可变的映射

 也可以使用 += 操作添加新的元素

 循环遍历映射

3.5迭代器( lterator)

  • 在Scala中,迭代器( lterator)不是一个集合,但是,提供了访问集合的一种方法
  • 迭代器包含两个基本操作: next 和 hasNext。next 可以返回迭代器的下一个元素,hasNext 用于检测是否还有下一个元素

3.6数组(Array)

数组是一种可变的、可索引的、元素具有相同类型的数据集合,它是各种高级语言中最常用的数据结构。Scala提供了参数化类型的通用数组类 Array[T],其中 T 可以是任意的Scala类型,可以通过显式指定类型或者通过隐式推断来实例化一个数组。

Array提供了函数ofDim来定义二维和三维数组,用法如下:

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

可以使用多级圆括号来访问多维数组的元素,例如myMatrix(O)(1)返回第一行第二列的元素

采用Array类型定义的数组属于定长数组,其数组长度在初始化后就不能改变。如果要定义变长数组,需要使用ArrayBuffer参数类型,其位于包 scala.collection.mutable 中。举例如下:

import scala.collection.mutable.ArrayBufferval 
val aMutableArr = ArrayBuffer(10,20,30)
aMutableArr += 40
aMutableArr.insert(2,60,40)
aMutableArr -= 40
var temp=aMutableArr.remove(2)

3.7元组(Tuple)

元组是不同类型的值的聚集。元组和列表不同,列表中各个元素必须是相同类型,而元组可以包含不同类型的元素

 基础语法介绍到这里,下篇博客总结 Scala的面向对象 与 函数式 编程。

原文地址:https://www.cnblogs.com/dongao/p/14306094.html