Scala 编程

Scala 编程

文章目录

一. Scala 简介

​ Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。

​ Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。

​ Scala 源代码被编译成 Java 字节码,所以它可以运行在 JVM 上,并可以调用现有的 Java 类库。

​ 函数编程范式更适合用于 Map/Reduce 和大数据模型,它摒弃了数据与状态的计算模型,着眼于函数本身,而非执行的过程的数据和状态的处理。函数范式逻辑清晰、简单,非常适合用于处理基于不变数据的批量处理工作,这些工作基本都是通过 map 和 reduce 操作转换数据后,生成新的数据副本,然后再进行处理。像 Spark,Flink等都是采用 Scala 开发的。

二. Scala 的安装与验证

2.1 下载安装

下载地址 选择的版本为 2.11.8

在这里插入图片描述

2.2 验证

​ 打开 dos 命令窗口,并输入 scala -version
在这里插入图片描述

2.3 IDEA 中使用 Scala

在这里插入图片描述

三. Scala 的特性

3.1 面向对象

​ Scala 是一种纯面向对象的语言,每个值都是对象。对象的数据类型一级行为由类和特质描述。

​ 类抽象机制的客栈有两种途径:

  • 子类继承
  • 灵活的混入机制

3.2 函数式编程

​ Scala 也是一种函数式语言,其函数也能当成值来用。Scala 提供了轻量级的语法用以定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化。Scala 的 case class 及其内置的模式匹配相当于函数式编程语言中常用的代数类型。更近一步,程序员可以利用 Scala 的模式匹配,编写类似正则表达式的代码处理 XML 数据。

3.3 静态类型

​ Scala 具备类型系统,通过编译时检查,保证代码的安全性和一致性,类型系统具体支持一下特性:

  • 泛型类
  • 协变和逆变
  • 标注
  • 类型参数的上下限约束
  • 把类别和抽象类型作为对象成员
  • 符合类型
  • 引用自己时显示指定类型
  • 视图
  • 多态方法

3.4 可扩展性

​ Scala 的设计秉承一项事实,即在实践中,某个领域特定的应用程序开发往往需要特定于该领域的语言扩展,Scala 提供了许多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构:

  • 任何方法可用作前缀或后缀操作符
  • 可以根据于其类型自动构造闭包

3.5 并发性

​ Scala 使用 Actor 作为其并发模型,Actor 是类似线程的实体,通过邮箱发收消息。Actor 可以复用线程,因此可以在程序中使用数百万个 Actor,而线程只能创建数千个。在 2.10 之后的版本中,使用 Akka 作为其默认 Actor 实现。

四. 基本语法

4.1 变量的声明与定义

​ Scala 通常使用关键字 val/var 进行变量的声明与定义,二者的区别在于:使用 val 定义的变量相当于 Java 中的常量,其值是不可以改变的,而由 var 定义的变量,其值是可以改变的

在这里插入图片描述

4.2 数据类型和操作符

4.2.1 数据类型

Scala笔记整理(一):scala基本知识_大数据_02

4.2.2 操作符
4.2.2.1 数学运算

​ Scala 中,你可以舍弃方法调用的空括号。例外就是如果方法带有副作用就加上括号,如 println(),不过如果方法没有副作用九可以去掉括号,如 String 上调用的 toLowerCase;

​ 你可以通过中缀操作符,加号(+),减号(-),乘号(*),除号(/)和余数(%),在任何数类型上调用数学方法, scala中的基础运算与java一致

在这里插入图片描述

4.2.2.2 关系与逻辑操作

​ 你可以用关系方法:大于(>),小于(<),大于等于(>=)和小于等于(<=)比较数类型,像等号操作符那样,产生一个Boolean结果。另外,你可以使用一元操作符!(unary_!方法)改变Boolean值

在这里插入图片描述

4.2.2.3 对象相等性

​ 其比较的是值,而不是 Java 概念中的地址值。

在这里插入图片描述

五. 控制结构与函数

5.1 if 表达式

​ Scala IF…ELSE 语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。可以通过下图来简单了解条件语句的执行过程:

if 语句结构

5.1.1 if 语句的语法格式
if(布尔表达式)
{
   
   // 如果布尔表达式为 true 则执行该语句块
}

​ 如果布尔表达式为 true 则执行大括号内的语句块,否则跳过大括号内的语句块,执行大括号之后的语句块。

object IfDemo {
   
  def main(args: Array[String]): Unit = {
   
    var x = 10;
    if (x < 20) {
   
      println("x < 20")
    }
  }
}
5.1.2 if … else 语法格式
if(布尔表达式){
   
   // 如果布尔表达式为 true 则执行该语句块
}else{
   
   // 如果布尔表达式为 false 则执行该语句块
}

​ if 语句后可以紧跟 else 语句,else 内的语句块可以在布尔表达式为 false 的时候执行。

object IfElseDemo {
   
  def main(args: Array[String]): Unit = {
   
    var x = 30;
    if (x < 20) {
   
      println("x 小于 20")
    } else {
   
      println("x 大于 20")
    }
  }
}
5.1.3 if … else if … else 语法格式
if(布尔表达式 1){
   
   // 如果布尔表达式 1 为 true 则执行该语句块
}else if(布尔表达式 2){
   
   // 如果布尔表达式 2 为 true 则执行该语句块
}else if(布尔表达式 3){
   
   // 如果布尔表达式 3 为 true 则执行该语句块
}else {
   
   // 如果以上条件都为 false 执行该语句块
}

​ if 语句后可以紧跟 else if…else 语句,在多个条件判断语句的情况下很有用。

object Test {
   
   def main(args: Array[String]) {
   
      var x = 30;

      if( x == 10 ){
   
         println("X 的值为 10");
      }else if( x == 20 ){
   
         println("X 的值为 20");
      }else if( x == 30 ){
   
         println("X 的值为 30");
      }else{
   
         println("无法判断 X 的值");
      }
   }
}
5.1.4 if … else 嵌套语句格式
if(布尔表达式 1){
   
   // 如果布尔表达式 1 为 true 则执行该语句块
   if(布尔表达式 2){
   
      // 如果布尔表达式 2 为 true 则执行该语句块
   }
}

​ if…else 嵌套语句可以实现在 if 语句内嵌入一个或多个 if 语句。

object Test {
   
   def main(args: Array[String]) {
   
        var x = 30;
        var y = 10;

         if( x == 30 ){
   
            if( y == 10 ){
   
            println("X = 30 , Y = 10");
         }
      }
   }
}

5.2 方法与函数

​ Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。

​ Scala 中的方法跟 Java 的类似,方法是组成类的一部分。

​ Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。

​ Scala 中使用 val 语句可以定义函数,def 语句定义方法。

5.2.1 方法的声明

​ 声明格式:

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

如果你不写等于号和方法主体,那么方法会被隐式声明为**抽象(abstract)**,包含它的类型于是也是一个抽象类型。

5.2.2 方法的定义

​ 方法定义由一个 def 关键字开始,紧接着是可选的参数列表,一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。

​ 定义格式:

def functionName ([参数列表]) : [return type] = {
   
   function body
   return [expr]
}
object add{
   
   def addInt( a:Int, b:Int ) : Int = {
   
      var sum:Int = 0
      sum = a + b

      return sum
   }
}

​ 如果方法没有返回值,可以返回为 Unit,这个类似于 Java 的 void, 实例如下:

object Hello{
   
   def printMe() : Unit = {
   
      println("Hello, Scala!")
   }
}
5.2.3 方法的调用

​ 调用格式:

functionName( 参数列表 )

​ 如果方法使用了实例的对象来调用,我们可以使用类似java的格式 (使用 . 号):

[instance.]functionName( 参数列表 )
object Test {
   
   def main(args: Array[String]) {
   
        println( "Returned Value : " + addInt(5,7) );
   }
   def addInt( a:Int, b:Int ) : Int = {
   
      var sum:Int = 0
      sum = a + b

      return sum
   }
}

5.3 控制结构

​ 有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。

​ 编程语言提供了更为复杂执行路径的多种控制结构。

​ 循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的流程图:

循环结构

	#### 5.3.1 循环类型
5.3.1.1 for 循环

​ 用来重复执行一系列语句直到达成特定条件达成,一般通过在每次循环完成后增加计数器的值来实现。

​ 语法格式:

for( var x <- Range ){
   
   statement(s);
}

​ 以上语法中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。i to j 为左右都为闭区间的范围,i until j 为左闭右开的范围区间

object ForDemo {
   
  def main(args: Array[String]): Unit = {
   
    for (i <- 1 to 10) {
   
      println(s"i=$i")
    }
    for (i <- 1 until 10) {
   
      println(s"i=$i")
    }

    println("=================双重for循环====================")
    for (i <- 1 to 3; j <- 1 to 5) {
   
      println(i * j)
    }
    println("====================守卫式 使用 if 条件=============================")
    for (i <- 1 to 10; j <- 1 to 10 if i == j) {
   
      println(s" i * j = $i * $j = ${i * j}")
    }
    println("====================推导式 使用 yield 接收返回结果=============================")
    // 如果 for 循环的循环体中以 yield 开始,那么此循环会构造出一个集合,每次迭代生成集合中的一个值
    // 可以使用变量接收产生的新集合
    val result = for (i <- 1 to 10) yield i % 2
    result.foreach(println(_))

    println("===================九九乘法表=============================")
    for (i <- 1 to 9; j <- 1 to i) {
   
      print(s"$j * $i = ${i * j}\t")
      if (i == j) {
   
        println()
      }
    }
    println("====================for 循环中使用 {} =============================")
    for {
   
      i <- 1 to 3
      from = 4 - i
      j <- from to 3
    }
      println(s"i=$i,j=$j")

    println("======================================遍历字符串===============================")
    val message = "dafsdfsdfadsfsd"
    for (elem <- message) print(elem + " ")
  }
5.3.1.2 while循环

​ 运行一系列语句,如果条件为true,会重复运行,直到条件变为false。

  • A :语法格式:
while(condition)
{
   
   statement(s);
}

​ 在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。

condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。

  • B:流程图

Scala 中的 while 循环

​ 在这里,while 循环的关键点是循环可能一次都不会执行。当条件为 false 时,会跳过循环主体,直接执行紧接着 while 循环的下一条语句。

object Test {
   
   def main(args: Array[String]) {
   
      // 局部变量
      var a = 10;

      // while 循环执行
      while( a < 20 ){
   
         println( "Value of a: " + a );
         a = a + 1;
      }
   }
}
5.3.1.1 do while循环

​ 类似 while 语句区别在于判断循环条件之前,先执行一次循环的代码块。

  • A:语法格式
do {
   
   statement(s);
} while( condition );
  • B:流程图

Scala 中的 do...while 循环

​ 请注意,条件表达式出现在循环的尾部,所以循环中的 statement(s) 会在条件被测试之前至少执行一次。如果条件为 true,控制流会跳转回上面的 do,然后重新执行循环中的 statement(s)。这个过程会不断重复,直到给定条件变为 false 为止。

object Test {
   
   def main(args: Array[String]) {
   
      // 局部变量
      var a = 10;

      // do 循环
      do{
   
         println( "Value of a: " + a );
         a = a + 1;
      }while( a < 20 )
   }
}
5.3.2 循环控制语句

​ 循环控制语句改变你代码的执行顺序,通过它你可以实现代码的跳转。Scala 以下几种循环控制语句:Scala 不支持 break 或 continue 语句,但从 2.8 版本后提供了一种中断循环的方式:breakable 和 break;语法格式如下:

// 导入以下包
import scala.util.control._

// 创建 Breaks 对象
val loop = new Breaks;

// 在 breakable 中循环
loop.breakable{
   
    // 循环
    for(...){
   
       ....
       // 循环中断
       loop.break;
   }
}

​ 流程图

img

import scala.util.control._

object Test {
   
   def main(args: Array[String]) {
   
      var a = 0;
      val numList = List(1,2,3,4,5,6,7,8,9,10);

      val loop = new Breaks;
      loop.breakable {
   
         for( a <- numList){
   
            println( "Value of a: " + a );
            if( a == 4 ){
   
               loop.break;
            }
         }
      }
      println( "After the loop" );
   }
}

​ 中断嵌套循环:

import scala.util.control._

object Test {
   
   def main(args: Array[String]) {
   
      var a = 0;
      var b = 0;
      val numList1 = List(1,2,3,4,5);
      val numList2 = List(11,12,13);

      val outer = new Breaks;
      val inner = new Breaks;

      outer.breakable {
   
         for( a <- numList1){
   
            println( "Value of a: " + a );
            inner.breakable {
   
               for( b <- numList2){
   
                  println( "Value of b: " + b );
                  if( b == 12 ){
   
                     inner.break;
                  }
               }
            } // 内嵌循环中断
         }
      } // 外部循环中断
   }
}
5.3.3 无限循环

​ 如果条件永远为 true,则循环将变成无限循环。我们可以使用 while 语句来实现无限循环:

object Test {
   
   def main(args: Array[String]) {
   
      var a = 10;
      // 无限循环
      while( true ){
   
         println( "a 的值为 : " + a );
      }
   }
}

六. 数组

​ Scala 语言中提供的数组是用来存储固定大小的同类型元素,数组对于每一门编辑应语言来说都是重要的数据结构之一。

​ 声明数组变量并不是声明 number0、number1、…、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、…、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。

​ 数组的第一个元素索引为0,最后一个元素的索引为元素总数减1。

​ scala中,有两种数组,一种是定长数组,另一种是变长数组

6.1 定长数组

​ 定长数组指的是数组的长度是不允许改变的,元素可以改变的数组。

  • 语法格式
// 通过指定长度定义数组
val / var 变量名 = new Array[元素类型](数组长度)
// 用元素直接初始化数组
val / var 变量名 = Array(元素1, 元素2, 元素3...)

Tips:

  • 在 scala 中,数组的泛型使用 [ ]来指定
  • 使用 ( ) 来获取元素
  • 示例

    • 定一个长度为10的整型数组

    • 设置第1个元素为110

    • 打印第1个元素

      C:\Users\21349>scala
      Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_252).
      Type in expressions for evaluation. Or try :help.
      
      scala> val a = new Array[Int](10)
      a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
      
      scala> a(0) = 110
      
      scala> println(a(0))
      110
      
      scala> println(a)
      [I@59e32960
      
      scala> println(a.toBuffer)
      ArrayBuffer(110, 0, 0, 0, 0, 0, 0, 0, 0, 0)
      

6.2 变长数组

​ 变长数组指的是数组的长度可变的,可以往数组中添加、删除元素

6.2.1 定义变长数组

​ 定义变长数组,需要提前导入 ArrayBuffer 类, import scala.collection.mutable.ArrayBuffer

  • 语法格式
// 创建空的ArrayBuffer变长数组,语法结构:
val / var a = ArrayBuffer[元素类型]()
// 创建带有初始元素的ArrayBuffer
val / var a = ArrayBuffer(元素1,元素2,元素3....)
  • 示例

    定义一个长度为0的整型变长数组

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val a = new ArrayBuffer[Int]()
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala>
6.2.2 添加/删除 元素
  • 使用 += 添加元素

  • 使用 -= 添加元素

  • 使用用++=追加一个数组到变长数组

    示例:

    1. 定义一个变长数组,包含以下元素: “hadoop”, “spark”, “flink”
    2. 往该变长数组添加一个"flume"元素
    3. 从该变长数组删除"hadoop"元素
    4. 再将一个数组,该数组包含"hive", "sqoop"追加到变长数组中
scala> // 定义变长数组

scala> val a = ArrayBuffer("hadoop","spark","scala","flink")
a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, spark, scala, flink)

scala> // 追加一个元素

scala> a += "flume"
res4: a.type = ArrayBuffer(hadoop, spark, scala, flink, flume)

scala> // 删除一个元素

scala> a -= "hadoop"
res5: a.type = ArrayBuffer(spark, scala, flink, flume)

scala> // 追加一个数组

scala> a ++= Array("hive","sqoop")
res6: a.type = ArrayBuffer(spark, scala, flink, flume, hive, sqoop)

scala>
6.2.3 遍历数组

​ 可以使用以下两种方式来遍历数组:

  • 使用 for表达式直接遍历数组中的元素

  • 使用 索引遍历数组中的元素

    示例一:

    1. 定义一个数组,包含以下元素1,2,3,4,5,6
    2. 使用for表达式直接遍历,并打印数组的元素
    scala> val a = Array(1,2,3,4,5,6)
    a: Array[Int] = Array(1, 2, 3, 4, 5, 6)
    
    scala> for(i <- a) println(i)
    1
    2
    3
    4
    5
    6
    
    scala>
    

    示例二:

    1. 定义一个数组,包含以下元素1,2,3,4,5
    2. 使用for表达式基于索引下标遍历,并打印数组的元素
    scala> val a = Array(1,2,3,4,5)
    a: Array[Int] = Array(1, 2, 3, 4, 5)
    
    scala> for(i <- 0 to a.length <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值