大数据开发初识Scala(第二十六篇)

204 阅读3分钟

一、什么是Scala

  1. Scala是一门多范式编程语言,一种类似Java编程语言
  2. Scala基于Java虚拟机,也就是基于JVM的一门编程语言
  3. Scala和Java可以无缝相互操作,Scala可以任意调用Java代码

二、Scala的基本使用

2.1、环境安装【Mac】

www.scala-lang.org/download/2.…

  1. 安装Scala之前需要配置JDK版本

  2. 解压到对应目录,

  3. 配置环境变量

    vi ~/.bash_profile

  4. 完整配置

    SCALA_HOME=/Users/strivelearn/DevelopEnvir/Scala/scala-2.12.17

    PATH=JAVAHOME/bin:JAVA_HOME/bin:{MAVEN_HOME}/bin:GRADLEHOME/bin:{GRADLE_HOME}/bin:{SCALA_HOME}/bin:$PATH:.

    export SCALA_HOME

  5. 生效配置

    source ~/.bash_profile

  6. 查看Scala当前配置

    scala -version

2.2、Scala命令行
  1. Scala命令行也称为Scala代码解释器,它会快速编译Scala代码为字节码,然后交给JVM来执行
  2. 在Scala命令行内,输入Scala代码,解释器会直接返回结果

image-20221105232639616

三、Scala基础语法

3.1、变量
  1. Scala中变量分为两种:可变var和不可变val

    scala> var a=1
    a: Int = 1
    ​
    scala> a=2
    a: Int = 2
    ​
    scala> val b=1
    b: Int = 1
    ​
    scala> b=3
    <console>:12: error: reassignment to val
           b=3
            ^
    
  2. 在实际工作中,针对不需要改变值的变量,通常建议使用val

  3. 无论声明val变量,还是声明var变量,都可以手动指定变量类型,如果不指定,scala会自动根据值,进行类型推断

    scala> val b:Int=1
    b: Int = 1
    ​
    scala> var c=1
    c: Int = 1
    
3.2、数据类型
  1. 基本数据类型:Byte、Char、Short、Int、Long、Float、Double、Boolean
  2. 增强版数据类型:StringOps、RichInt、RichDouble、RichChar等
3.3、操作符
  1. Scala的算术操作符与Java的算术操作符没有什么区别
  2. 比如+、-、*、/、%等
3.4、表达式
  1. if表达式。可以将if表达式赋予一个变量

    scala的if表达式是有返回值的,就是if或者else中最后一行语句返回的值

    scala> if(c>1) 1 else 0
    res1: Int = 0
    
  2. if表达式的类型自动推断

3.5、语句终结符
  1. Scala默认不需要语句终结符,它将每一行作为一个语句
  2. 如果一行要放多条语句,则前面的语句必须使用语句终结符
  3. 语句终结符就是我们平时使用的分号(;)
3.6、循环

scala多行输入:输入:paste,输入ctrl+d结束

  1. print和println

    print在打印的时候,不加换行符;println会加换行符

  2. for循环

    scala> :paste
    // Entering paste mode (ctrl-D to finish)
    ​
    val n =10 
    for(i<- 1 to n)
    println(i)
    ​
    // Exiting paste mode, now interpreting.1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    n: Int = 10
    
  3. while循环

    scala> :paste
    // Entering paste mode (ctrl-D to finish)var n =10
    while(n>0)
    {
    println(n)
    n-=1
    }
    ​
    // Exiting paste mode, now interpreting.10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    n: Int = 0
    
  4. if守卫

    在循环的时候就判断条件

    ​
    scala> for(i<- 1 to 10 if i%2==0) println(i)
    2
    4
    6
    8
    10
    
  5. for推导式

    在迭代数字的时候,我们可以使用关键词yield,来指定规则对迭代出的数字进行处理,并且创建一个新的集合

    scala> for(i<- 1 to 10) yield i * 2
    res2: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
    

四、Scala集合体系

官网文档:www.scala-lang.org/api/2.12.17…

  1. 可变集合 scala.collection.mutable
  2. 不可变集合 scala.collection.immutable【默认】

Scala集合

4.1、Set(mutable、immutable)
scala> val s=Set(1,2,3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> val s=scala.collection.mutable.Set(2,3,4)
s: scala.collection.mutable.Set[Int] = Set(2, 3, 4)
//往set集合中添加元素
scala> s+=5
res0: s.type = Set(5, 2, 3, 4)
4.2、List(代表一个不可变的列表)
  1. List的head、tair以及::操作符

    scala> val l=List(1,2,3,4)
    l: List[Int] = List(1, 2, 3, 4)
    ​
    scala> l.head
    res1: Int = 1
    ​
    scala> l.tail
    res2: List[Int] = List(2, 3, 4)
    ​
    scala> l.head::l.tail
    res4: List[Int] = List(1, 2, 3, 4)
    
  2. ListBuffer:可以动态增加或者移除元素

    scala>  val lb=scala.collection.mutable.ListBuffer[Int]()
    lb: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
    ​
    scala> lb+=1
    res5: lb.type = ListBuffer(1)
    ​
    scala> lb+=2
    res6: lb.type = ListBuffer(1, 2)
    
4.3、Map
  1. Map是一种可迭代的键值对(key/value)结构
  2. Map分为可变和不可变,默认情况下使用的是不可变的Map
scala> val ages=Map("jack"->30,"tom"->25)
ages: scala.collection.immutable.Map[String,Int] = Map(jack -> 30, tom -> 25)
​
scala> val ageMap=Map(("jack",30),("tom",25))
ageMap: scala.collection.immutable.Map[String,Int] = Map(jack -> 30, tom -> 25)
​
scala> ageMap("jack")
res7: Int = 30
​
scala> ageMap("java")
java.util.NoSuchElementException: key not found: java
  at scala.collection.immutable.Map$Map2.apply(Map.scala:227)
  ... 28 elided
​

Map根据key如果获取不到值,会直接抛出异常。所以可以在获取值前进行判断操作

scala> val age=if(ageMap.contains("java")) ageMap("java") else 0
age: Int = 0

但是这样太麻烦了,直接使用getOrElse

scala> val age=ageMap.getOrElse("java",0)
age: Int = 0
4.4、Array
  1. Scala中Array的含义与Java中的数组类似,长度不可变
  2. 由于Scala与Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上就是Java数组
  3. 数组初始化后,长度就固定下来了,元素全部根据其类型初始化,也可以直接使用Array()创建数组,元素类型自动推断
scala> val a=new Array[Int](10)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
​
scala> val b=Array("Hello","World")
b: Array[String] = Array(Hello, World)
4.5、ArrayBuffer
  1. Scala中ArrayBuffer与Java中的ArrayList类似,长度可变
  2. ArrayBuffer:添加元素、移除元素
  3. Array与ArrayBuffer可以互相转换
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
​
scala> val ab=new ArrayBuffer[Int]()
ab: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
​
scala> ab+=1
res9: ab.type = ArrayBuffer(1)
​
scala> ab+=(2,3,4)
res10: ab.type = ArrayBuffer(1, 2, 3, 4)
​
scala> ab.insert(3,30)
​
scala> ab
res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 30, 4)
​
scala> ab.toArray
res14: Array[Int] = Array(1, 2, 3, 30, 4)
​
scala> a.toBuffer
res16: scala.collection.mutable.Buffer[Int] = ArrayBuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
​
4.6、Tuple
  1. 称为元祖,它与Array类似,都是不可变的,但与列表不同的是元组可以包含不同类型的元素
  2. Tuple中的元素下标从1开始
  3. 目前Scala支持的元祖最大长度为22,对于更大长度可以使用集合或者数组
scala> val t=(1,3.14,"Hello")
t: (Int, Double, String) = (1,3.14,Hello)
​
scala> t._1
res17: Int = 1
​
scala> t._2
res18: Double = 3.14

五、Scala函数

  1. 在Scala中定义函数需要使用def关键字,函数包含函数名、参数、函数体
  2. Scala要求必须给出函数所有参数的类型,但是函数返回值的类型不是必须的(因为可以自动推断)
  3. 函数中最后一行代码的返回值就是整个函数的返回值,不需要使用return,这点与Java不同
scala> def sayHello(name:String)=println("Hello:"+name)
sayHello: (name: String)Unit
​
scala> sayHello("zhangsan")
Hello:zhangsan
5.1、函数的参数
  1. 默认参数:有时我们调用某些函数时,不希望给出参数的具体值,而是希望使用参数自身默认的值
  2. 带名参数:在调用函数时,也可以不按照函数定义的参数顺序来传递参数,而是使用带名参数的方式来传递
  3. 可变参数:有时我们需要将函数定义为参数个数可变的形式,则此时可以使用可变参数定义函数
scala> def sayHi(word:String="nihao")=println("Hello:"+word)
sayHi: (word: String)Unit
​
scala> sayHi()
Hello:nihao
​
scala> sayHi(word="wawo")
Hello:wawo
scala> :paste
// Entering paste mode (ctrl-D to finish)
​
def sum(muns:Int*)={
var res=0
for(num<-muns)res+=num
res
}
​
// Exiting paste mode, now interpreting.
​
sum: (muns: Int*)Int
​
​
scala> sum(1,2,3)
res0: Int = 6
​
scala> sum(2,3,4,5)
res1: Int = 14
5.2、特殊的函数-过程
  1. 在Scala中,定义函数时,如果函数体直接在花括号里面而没有使用=链接,则函数的返回值类型就是Unit,这样的函数称为过程函数
  2. 过程函数通常用于不需要返回值的函数
  3. 过程函数还有一种写法,就是把函数的返回值类型显式定义为Unit
scala> def si(name:String){"hello:"+name}
si: (name: String)Unit
​
scala> def si2(name:String):Unit="hello:"+name
si2: (name: String)Unit