Spark大数据分与实践笔记(Scala语言基础-2)

发布于:2023-01-11 ⋅ 阅读:(265) ⋅ 点赞:(0)

目录

1.2 Scala的基础语法

1.2.1 Scala有两种类型的变量

1.2.2 数据类型

1.2.3 算术和操作符重载

1.2.4 控制结构语句

1.2.5 方法和函数

1.3 Scala的数据结构

1.3.1 数组

1.3.2 元组

1.3.3 集合


1.2 Scala的基础语法

每种编程语言都有一套自己的语法规范,Scala语言也不例外,同样需要遵守一定的语法规范。

声明值和变量

1.2.1 Scala有两种类型的变量

  • 使用关键字var声明的变量,值是可变的;
  • 使用关键字val声明的变量,也叫常量,值是不可变的。

var myVar: String = "Hello" //使用关键字var声明的变量

val age: Int = 10           //使用关键字val声明的变量

有以下几个事项需要注意:

  1. Scala中的变量在声明时必须进行初始化。
  • 使用var声明的变量可以在初始化后再次对变量进行赋值;
  • 使用val声明的常量的值不可被再次赋值。

声明变量时,我们可以不给出变量的类型,因为在初始化的时候,Scala的类型推断机制能够根据变量的初始化的值自动推算出来。

上述声明变量myVar和age的代码,等同于下列代码:

var myVar = "Hello"   //使用关键字var声明的变量

val age = 10           //使用关键字val声明的变量

  1. 使用关键字var或val声明变量时,后面紧跟的变量名称不能和Scala中的保留字重名,而且变量名可以以字母或下划线开头,且变量名是严格区分大小写的。

1.2.2 数据类型

任何一种编程语言都有特定的数据类型,Scala也不例外。与其他语言相比,Scala中的所有值都有一个类型,包括数值和函数。

 

Scala中数据类型的层次结构

从图1-11中可以看出,Any是所有类型的超类型,也称为顶级类型,它包含两个直接子类,具体如下:

  • AnyVal表示值类型,值类型描述的数据是一个不为空的值,而不是一个对象。它预定义了9种类型,分别是Double、Float、Long、Int、Short、Byte、Unit、Char和Boolean。其中,Unit是一种不代表任何意义的值类型,它的作用类似Java中void。
  • AnyRef表示引用类型。可以认为,除值以外,所有类型都继承自AnyRef。

在Scala数据类型层级结构底部,还有两个数据类型,分别是Nothing和Null,具体介绍如下:

  • Nothing所有类型的的子类型,也称为底部类型。它觉的用途是发出终止信号,例如抛出异常、程序退出或无限循环。
  • Null所有引用类型的子类型,它主要用途是与其他JVM语言互操作,几乎不在Scala代码中使用。

1.2.3 算术和操作符重载

Scala中算术操作符(+、-、*、/、%)的作用和Java是一样的,位操作符(&、|、>>、<<)也是一样的。特别强调的是,Scala的这些操作符其实是方法例如,a+b其实是a.+(b)的简写。

 

Scala没有提供操作符++和--。如果我们想实现递增或者递减的效果,可以使用“+=1”或者“-=1”这种方式来实现。

1.2.4 控制结构语句

在Scala中,控制结构语句包括条件分支语句和循环语句

  1. 条件分支语句

//if语句的语法格式如下:

if (布尔表达式1){

        语句块

}

// if……else语句

if (布尔表达式1){

        语句块

}

else {

       语句块

}

// if……else if……else语句

if (布尔表达式1){

        语句块

} else if(布尔表达式2){

         语句块

} else if(布尔表达式3){

       语句块

} else {

       语句块

}

// if……else嵌套语句

if (布尔表达式1){   

       语句块

               if(布尔表达式2){

                      语句块

               }

}else if (布尔表达式3){

        语句块

               else if (布尔表达式4){

                      语句块

                }

}else{

         语句块

}

示例代码如下:

  1. 循环语句

Scala中的for语句和Java中的循环语句在语法上有较大的区别,我们介绍一下Scala中的for循环语句。

for循环语句的语法如下:

for(变量<-表达式/数组/集合){

         循环语句;

}

下面,我们通过从0循环到9,每循环一次则就将该值打印输出进行操作演示。在Scala语法中,可以使用”0 to 9”表示从0到9的范围,范围包含9,示例代码如下:

Dos 下:

IDEA下:

 

//0 1 2 3 4 5 6 7 8 9

Scala在for循环语句中可以通过使用if判断语句过滤一些元素,多个过滤条件用分号分隔开。例如,输出0-9范围中大于5的偶数,示例代码如下:

 Scala中的while循环语句和Java中的完全一样,语法格式如下:

while(布尔表达式){

         循环语句;

}

下面,我们通过打印输出奇数的案例来演示while的使用。假设有一个变量x=1,判断是否小于10,如果是则打印输出,然后再进行+2运算。示例代码如下:

do…while循环语句的语法格式如下:

do{

       循环语句;

}while(布尔表达式)

do…while循环语句与while语句的主要区别是,do…while语句的循环语句至少执行一次,示例代码如下:

 

1.2.5 方法和函数

在Scala中,它和Java一样也是拥有方法和函数。Scala的方法是类的一部分,而函数是一个对象可以赋值给一个变量。Scala中可以使用def语句和val语句定义函数,而定义方法只能使用def语句。下面分别对Scala的方法和函数进行讲解。

  1. 方法

Scala方法的定义格式如下:

def functionName ([参数列表]):[return type]={

         function body

         return [expr]

}

下面定义一个方法add,实现两个数相加求和,示例代码下:

  1. def add(a:Int,b:Int):Int={
  2.   var sum:Int = 0
  3.   sum = a + b
  4.   return sum
  5. }

Scala的方法调用的格式如下:

  1. //没有使用实例的对象调用格式
  2. functionName(参数列表)
  3. //方法使用实例的对象来调用,我们可以使用类似Java的格式(“.”号)
  4. [instance.]functionName(参数列表)

下面,在类Test中,定义一个方法addInt,实现两个整数相加求和。在这里, 我们通过“类名.方法名(参数列表)”来进行调用,示例代码如下:

  1. scala> :paste                         # 多行输入模式的命令
  2. // Entering paste mode (ctrl-D to finish)
  3. object Test{
  4. def addInt(a:Int,b:Int):Int={
  5.   var sum:Int =0
  6.   sum = a + b
  7.   return sum
  8.  }
  9. }
  10. // Exiting paste mode, now interpreting. # Ctrl+d结束多行输入模式
  11. defined object Test
  12. scala> Test.addInt(4,5)      # 方法调用
  13. res0: Int = 9

  1. 函数

Scala中的函数是一个对象,可以赋值给一个变量。

Scala函数的定义语法格式如下:

val functionName =([参数列表])=>function body

下面,定义一个函数addInt,实现实现两个整数相加求和,示例代码如下:

  1. scala> val addInt =(a:Int,b:Int) => a+b
  2. addInt: (Int, Int) => Int = <function2>
  3. scala> addInt(6,7)
  4. res1: Int = 13

  1. 方法转换成函数

方法转换成函数的格式如下:

val f1 = m _

在上述的格式中,方法名m后面紧跟一个空格和下划线,是为告知编译器将方法转换成函数,而不是要调用这个方法。下面,定义一个方法m,实现将方法m转成函数,示例代码如下:

  1. scala> def m(x:Int,y:Int):Int=x*y          # 方法
  2. m: (x: Int, y: Int)Int
  3. scala> val f = m _
  4. f: (Int, Int) => Int = <function2>          # 函数
  5. scala> f(2,3)
  6. res2: Int = 6

小提示:

Scala方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归方法来说,必须要指定返回类型。

1.3 Scala的数据结构

在编写程序代码时,经常需要用到各种数据结构,选择合适的数据结构可以带来更高的运行或者存储效率,Scala提供了许多数据结构,例如常见的数组、元组和集合等。

1.3.1 数组

数组(Array)主要用来存储数据类型是每个人元素。

  1. 数组定义与使用

Scala中的数组分为定长数组变长数组,这两种数组的定义方式如下:

New Array[T] (数组长度)         //定义定长数组

ArrayBuffer[T]( )                //定义变长数组

注意:定义定长数组,需要使用new关键字,而定义变长数组时,则需要导包import scala.collection.mutable.ArrayBuffer。

下面,通过一个例子来演示Scala数组简单使用,具体代码如文件1-2所示。

Ch01_ArrayDemo.scala

package cn.itcast.scala

import scala.collection.mutable.ArrayBuffer

object Ch01_ArrayDemo {

  def main(args: Array[String]): Unit = {

    //定义定长数组:定义长度为8的定长数组,数组中的每个元素初始化为0

    val arr1 = new Array[Int](8)

    //打印数组,内容是数组的hashcode值

    println(arr1)

//定义变长数组(数组缓冲),需要导入包:import scala.collection.mutable.ArrayBuffer

    val arr2 = ArrayBuffer[Int]()

    //向变长数组中追加元素

    arr2 += 1

    //打印变长数组

    println(arr2)

    //向变长数组中追加多个元素

    arr2 += (2,3,4,5)

    println(arr2)

    //追加一个定长数组

    arr2 ++= Array(6,7)

    println(arr2)

    //追加一个变长数组(数组缓冲)

    arr2 ++= ArrayBuffer(8,9)

    println(arr2)

    //在变长数组的某个位置插入元素

    arr2.insert(0,-1,0)

    println(arr2)

    //删除数组的某个元素

    arr2.remove(0)

    println(arr2)

  }

}

  1. 数组的遍历

Scala中,如果想要获取数组中的每一个元素,则需要将数组进行遍历操作。

Ch02_ArrayTraversal.scala

package cn.itcast.scala

object Ch02_ArrayTraversal {

  def main(args: Array[String]): Unit = {

    //定义定长数组

    //val array = new Array[Int](8) //方式1

    val myArr = Array(1.9, 2.9, 3.4, 3.5) //方式2

    //打印输出数组中的所有元素

    for(x<-myArr){

      print(x+" ")

    }

    println()

    //计算数组中所有元素的和

    var total = 0.0

    for(i <- 0 to (myArr.length-1)){

      total += myArr(i)

    }

    println("总和为:"+total)

    //查找数组中的最大值

    var max = myArr(0)

    for(i <- 1 to (myArr.length-1)){

      if(max < myArr(i)){

        max = myArr(i)

      }

    }

    println("最大值为:"+max)

  }

}

  1. 数组转换

数组转换就是通过yield关键字将原始的数组进行转换,会产生一个新的数组,然而原始的数组保持不变。定义一个数组,实现将偶数取出乘以10后生成一个新的数组,具体代码如文件1-4所示。

Ch03_ArrayYieldTest.scala

package cn.itcast.scala

object Ch03_ArrayYieldTest {

  def main(args: Array[String]): Unit = {

    //定义一个数组

    var arr = Array(1,2,3,4,5,6,7,8,9)

    //将偶数取出乘以10后再生成一个新的数组

    val newArr = for (e <- arr if e%2 == 0) yield e * 10

    println(newArr.toBuffer) //将定长数组转为变长数组

  }

}

     

1.3.2 元组

Scala的元组是对多个不同类型对象的一种简单封装,它将不同的值用小括号括起来,并用逗号作分隔,即表示元组。

  1. 创建元组

创建元组的语法格式如下:

  val tuple=(元素,元素...)

下面,通过简单的例子进行演示创建元组,例如:创建一个包含String类型、Double类型以及Int类型的元组,具体代码如下:

scala> val tuple = ("itcast",3.14,65535)

tuple: (String, Double, Int) = (itcast,3.14,65535)

  1. 获取元组中的值

在Scala中,获取元组中的值是通过下划线加脚标(例如:tuple._1,tuple._2)来获取的,元组中的元素脚标是从1开始的。

scala> tuple._1                         # 获取第一个值

res0: String = itcast

scala> tuple._2                         # 获取第一个值

res1: Double = 3.14

  1. 拉链操作

在Scala的元组中,可以通过使用“zip”命令将多个值绑定在一起。例如,定义两个数组,分别是score和names,将这两个数组捆绑在一起,具体代码如下:

scala> val scores = Array(88,95,80)

scores: Array[Int] = Array(88, 95, 80)

scala> val names =Array("zhangsan","lisi","wangwu")

names: Array[String] = Array(zhangsan, lisi, wangwu)

scala> names.zip(scores)

res2: Array[(String, Int)] = Array((zhangsan,88), (lisi,95), (wangwu,80))

注:当两个数组个数不等时,会自动适配较短长度,多余元素无相应匹配元素会被自动抛弃。

1.3.3 集合

在Scala中,集合有三大类: List、Set以及Map。

Scala 集合分为可变的(mutable)和不可变(immutable)的集合。其中,可变集合可以在适当的地方被更新或扩展,意味着可以对集合进行修改、添加、移除元素;不可变集合类,相比之下,初始化后就永远不会改变。

  1. List

在Scala中,List列表和数组类似,列表的所有元素都具有相同类型。这里的List默认是不可变列表,如果要定义可变列表,需要导入import scala.collection.mutable.ListBuffer包。

定义不同类型列表List,具体代码如下:

// 字符串

val fruit: List[String] =List("apples","oranges","pears")

// 整型

val nums: List[Int] = List(1, 2, 3, 4)

//

val empty: List[Nothing] = List()

// 二维列表

val dim: List[List[Int]] =

            List(

            List(1, 0, 0),

            List(0, 1, 0),

            List(0, 0, 1)

 )

在Scala中,可以使用“Nil”和“::”操作符来定义列表。

// 字符串

val fruit = "apples":: ("oranges":: ("pears" :: Nil))

// 整型

val nums = 1 :: (2 :: (3 :: ( 4 :: Nil)))

// 空列表

val empty = Nil

// 二维列表

val dim = (1 :: (0 :: (0 :: Nil))) ::

                (0 :: (1 :: (0 :: Nil))) ::

                (0 :: (0 :: (1 :: Nil))) :: Nil

Scala也提供了很多操作List的方法,如表1-1所示。

方法名称

相关说明

head

返回列表第一个元素

tail

 返回一个列表,包含除了第一元素之外的其他元素

isEmpty 

在列表为空时返回true,否则返回false

take

获取列表前n个元素

contains

判断是否包含指定元素

示例代码如下:

Ch04_ListTest.scala

package cn.itcast.scala

object Ch04_ListTest {

  def main(args: Array[String]): Unit = {

    //定义List集合

    //val fruit:List[String] = List("apples","oranges","pears")

    val fruit = "apples"::("oranges"::("pears"::Nil))

    val nums = Nil

    println("Head of fruit:" + fruit.head)

    println("Tail of fruit:" + fruit.tail)

    println("check if fruit is empty:"+fruit.isEmpty)

    println("check if nums is empty:"+nums.isEmpty)

    println("Take of fruit:"+fruit.take(2))

    println("contains of fruit oranages:"+fruit.contains("oranges"))

  }

}

  1. Set

在Scala中,Set是没有重复对象的集合,所有元素都是唯一的。默认情况下,Scala 使用不可变Set集合,若想使用可变的Set集合,则需要引入 scala.collection.mutable.Set 包。

定义Set集合的语法格式如下:

val set: Set[Int] = Set(1,2,3,4,5)

Scala提供了很多操作Set集合的方法。接下来,我们列举一些操作Set集合的常见方法,具体如表1-2所示。

方法名称

相关说明

head

返回Set集合的第一个元素

tail

返回除第一个之外的所有元素组成的Set集合

isEmpty 

Set集合为空,则返回true,否则返回false

take

获取Set集合前n个元素

contains

判断Set集合是否包含指定元素

具体代码如文件1-6W所示。

Ch05_SetTest.scala

package cn.itcast.scala

object Ch05_SetTest {

  def main(args: Array[String]): Unit = {

    //定义Set集合

    val site = Set("Itcast","Google","Baidu")

    val nums:Set[Int] = Set()

    println("第一个网站是:"+site.head)

    println("最后一个网站是:"+site.tail)

    println("site集合是否为空:"+site.isEmpty)

    println("nums集合是否为空:"+nums.isEmpty)

    println("查看site集合的前两个网站:"+nums.take(2))

    println("site集合中是不包含网站Google"+site.contains("Google"))

  }

}

  1. Map

在Scala中,Map是一种可迭代的键值对(key/value)结构,并且键是唯一的,值不一定是唯一的,所有的值都是通过键来获取的。Map中所有元素的键与值都存在一种对应关系,这种关系即为映射。Map有两种类型,可变集合与不可变集合,默认是不可变Map。若需要使用可变的Map集合,则需要引入 import scala.collection.mutable.Map 类。

定义Map集合的语法格式如下:

var A:Map[Char,Int] = Map( -> , -> ...)  //Map键值对,键为Char,值为Int

Scala也提供了很多操作Map集合的方法。接下来,我们列举一些操作Map集合的常见方法,具体如下所示。

方法名称

相关说明

()

根据某个键查找对应的值,类似于Java中的get()

contains()

检查Map中是否包含某个指定的键

getOrElse()

判断是否包含键,若包含返回对应值,否则返回其他的

keys

返回Map所有的键(key)

values

返回Map所有的值(value)

isEmpty

若Map为空时,返回true

示例如文件所示:

package cn.itcast.scala

object Ch06_MapTest {

  def main(args: Array[String]): Unit = {

    //定义Map集合

    val colors = Map("red"-> "#FF0000",

      "azure"-> "#F0FFFF",

      "peru"-> "#CD853F")

    val peruColor = if(colors.contains("peru")) colors("peru") else 0

    val azureColor = colors.getOrElse("azure",0)

    println("获取colors中键为red的值:"+colors("red"))

    println("获取colors中所有的键:"+colors.keys)

    println("获取colors中所有的值:"+colors.values)

    println("检测colors是否为空:"+colors.isEmpty)

    println("判断colors中是否包含键peru,包含则返回对应的值,否则返回0"+peruColor)

    println("判断colors中是否包含键azure,包含则返回对应的值,否则返回0"+azureColor)

  }

}

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到