【Scala】scala的基本語法

目錄

變量

定義變量

定義一個變量

使用類型推斷來定義變量

惰性賦值

字符串

使用雙引號

使用插值表達式

使用三引號

數據類型

運算符

scala類型層次結構

條件表達式

有返回值的if

塊表達式

for循環

for表達式

簡單循環

嵌套循環

守衛

for推導式

while循環

break和continue

實現break

實現continue

方法

定義方法

方法參數

默認參數

帶名參數

變長參數

方法調用方式

後綴調用法

中綴調用法

花括號調用法

無括號調用法

返回值類型推斷

函數

定義函數

方法和函數的區別

方法轉換爲函數

數組

定長數組

變長數組

變長數組添加/修改/刪除元素

遍歷數組

數組常用算法

元組

定義元組

訪問元組

列表

不可變列表

可變列表

可變列表操作

列表常用操作

Set

不可變集

基本操作

可變集

映射(Map)

不可變Map

可變Map

Map基本操作

iterator迭代器


  • 變量

定義變量

val/var 變量標識:變量類型 = 初始值

val:定義的是不可重新賦值的變量

var:定義的是可重新賦值的變量

 

定義一個變量

val name:String = "tom"

 

使用類型推斷來定義變量

scala可以自動根據變量的值來自動推斷變量的類型,這樣編寫代碼更加簡潔

 

惰性賦值

在企業的大數據開發中,有時候會編寫非常複雜的SQL語句,這些SQL語句可能有幾百行甚至上千行。這些SQL語句,如果直接加載到JVM中,會有很大的內存開銷。當有一些變量保存的數據較大時,但是不需要馬上加載到JVM內存。可以使用惰性賦值來提高效率

語法格式:

lazy val/var 變量名 = 表達式

 

  • 字符串

scala提供多種定義字符串的方式,將來我們可以根據需要來選擇最方便的定義方式。

1.使用雙引號

2.使用插值表達式

3.使用三引號

 

使用雙引號

語法:

val/var 變量名 = “字符串”

 

使用插值表達式

在定義字符串之前添加s

在字符串中,可以使用${}來引用變量或者編寫表達式

語法:

val/var 變量名 = s"${變量/表達式}字符串"

 

 

使用三引號

如果有大段的文本需要保存,就可以使用三引號來定義字符串。例如:保存一大段的SQL語句。三個引號中間的所有字符串都將作爲字符串的值。

語法:

val/var 變量名 = """字符串1 字符串2""" 

 

  • 數據類型

基礎類型

類型說明

Byte

8位帶符號整數

Short

16位帶符號整數

Int

32位帶符號整數

Long

64位帶符號整數

Char

16位無符號Unicode字符

String

Char類型的序列(字符串)

Float

32位單精度浮點數

Double

64位雙精度浮點數

Boolean

true或false

  1. scala中所有的類型都使用大寫字母開頭
  2. 整形使用Int而不是Integer
  3. scala中定義變量可以不寫類型,讓scala編譯器自動推斷

 

  • 運算符

類別

操作符

算術運算符

+、-、*、/

關係運算符

>、<、==、!=、>=、<=

邏輯運算符

&&、|| 、!

位運算符

&、、^、<<、>>

1.scala中沒有,++、--運算符

2.與Java不一樣,在scala中,可以直接使用==、!=進行比較,它們與equals方法表示一致。而比較兩個對象的引用值,使用eq

 

  • scala類型層次結構

類型

說明

Any

所有類型的父類,,它有兩個子類AnyRef與AnyVal

AnyVal

所有數值類型的父類

AnyRef

所有對象類型(引用類型)的父類

Unit

表示空,Unit是AnyVal的子類,它只有一個的實例() 它類似於Java中的void,但scala要比Java更加面向對象

Null

Null是AnyRef的子類,也就是說它是所有引用類型的子類。

它的實例是null可以將null賦值給任何對象類型

Nothing

所有類型的子類不能直接創建該類型實例,某個方法拋出異常時,返回的就是Nothing類型,因爲Nothing是所有類的子類,那麼它可以賦值爲任何類型

 

  • 條件表達式

條件表達式就是if表達式,if表達式可以根據給定的條件是否滿足,根據條件的結果(真或假)決定執行對應的操作。scala條件表達式的語法和Java一樣。

 

有返回值的if

1.在scala中,條件表達式也是有返回值的

2.在scala中,沒有三元表達式,可以使用if表達式替代三元表達式

例:

val sex = "male" 
val result = if(sex == "male") 1 else 0

 

塊表達式

1.scala中,使用{}表示一個塊表達式

2.和if表達式一樣,塊表達式也是有值的,就是最後一個表達式的值

val a = {
      println("1 + 1")
      1 + 1
      }

 

  • for循環

在scala中,可以使用for和while,但一般推薦使用for表達式,因爲for表達式語法更簡潔

 

for表達式

語法:

for(i <- 表達式/數組/集合) { // 表達式 }

 

簡單循環

例:使用for表達式打印1-10的數字

val nums = 1.to(10)
for(i <- nums) println(i)

 

嵌套循環

for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")} 

 

守衛

for表達式中,可以添加if判斷語句,這個if判斷就稱之爲守衛。我們可以使用守衛讓for表達式更簡潔

語法:

for(i <- 表達式/數組/集合 if 表達式) { 
// 表達式 
} 

例:

// 添加守衛,打印能夠整除3的數字

for(i <- 1 to 10 if i % 3 == 0) println(i) 

 

for推導式

在for循環體中,可以使用yield表達式構建出一個集合,我們把使用yield的for表達式稱之爲推導式

例:生成一個10、20、30...100的集合

// for推導式:for表達式中以yield開始,該for表達式會構建出一個集合
val v = for(i <- 1 to 10) yield i * 10

 

 

  • while循環

scala中while循環和Java中是一致的

 

例:打印1-10的數字

scala> var i = 1
i: Int = 1
 
scala> while(i <= 10) {
     | println(i)
     | i = i+1
     | }

 

  • break和continue

1.scala中,沒有break/continue關鍵字

2.如果一定要使用break/continue,就需要使用scala.util.control包的Break類的breable和break方法

 

實現break

1.導入Breaks包import scala.util.control.Breaks._

2.使用breakable將for表達式包起來

3.for表達式中需要退出循環的地方,添加break()方法調用

例:使用for表達式打印1-100的數字,如果數字到達50,退出for表達式

// 導入scala.util.control包下的Break
import scala.util.control.Breaks._
breakable{
    for(i <- 1 to 100) {
        if(i >= 50) break()
        else println(i)
    }
}

 

實現continue

1.continue的實現與break類似,但有一點不同:

2.實現continue是用breakable{}將for表達式的循環體包含起來

 

例:打印1-100的數字,使用for表達式來遍歷,如果數字能整除10,不打印

// 導入scala.util.control包下的Break    
import scala.util.control.Breaks._
for(i <- 1 to 100 ) {
   breakable{
       if(i % 10 == 0) break()
       else println(i)
  }
}

 

  • 方法

一個類可以有自己的方法,scala中的方法和Java方法類似。但scala與Java定義方法的語法是不一樣的

 

定義方法

1.參數列表的參數類型不能省略

2.返回值類型可以省略,由scala編譯器自動推斷

3.返回值可以不寫return,默認就是{}塊表達式的值

語法:

def methodName (參數名:參數類型, 參數名:參數類型) : [return type] = {
   // 方法體:一系列的代碼
}

 例:定義一個方法,實現兩個整形數值相加,返回相加後的結果,調用該方法

scala> def add(a:Int, b:Int) = a + b
m1: (x: Int, y: Int)Int
​
scala> add(10,20)
res9: Int = 30

 

  • 方法參數

scala中的方法參數,使用比較靈活。它支持以下幾種類型的參數:

1.默認參數

2.帶名參數

3.變長參數

 

默認參數

在定義方法時可以給參數定義一個默認值

例:

def add(x:Int = 10, y:Int = 20) = x + y
add()

 

帶名參數

在調用方法時,可以指定參數的名稱來進行調用

例:

def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)

 

變長參數

如果方法的參數是不固定的,可以定義一個方法的參數是變長參數

語法:

def 方法名(參數名:參數類型*):返回值類型 = {
    方法體
}

例:

def add(num:Int*) = num.sum
add(1,2,3,4,5)

 

  • 方法調用方式

在scala中,有以下幾種方法調用方式

1.後綴調用法

2.中綴調用法

3.花括號調用法

4.無括號調用法

 

後綴調用法

語法:

對象名.方法名(參數)

例:使用後綴法Math.abs求絕對值

Math.abs(-1)

 

中綴調用法

語法:注意空格

對象名 方法名 參數

例:使用中綴法Math.abs求絕對值

Math abs -1 

 

花括號調用法

語法:方法只有一個參數,才能使用花括號調用法

對象名.方法名{
    // 表達式1
    // 表達式2
}

例:使用花括號調用法Math.abs求絕對值

 Math.abs{-10}

 

無括號調用法

語法:如果方法沒有參數,可以省略方法名後面的括號

方法名

例:定義一個無參數的方法,打印"hello",使用無括號調用法調用該方法

def m3()=println("hello")
m3()

 

  • 返回值類型推斷

1.scala定義方法可以省略返回值,由scala自動推斷返回值類型。

2.定義遞歸方法,不能省略返回值類型

 

例:定義遞歸方法(求階乘)

def m2(x:Int) = {
     | if(x<=1) 1
     | else m2(x-1) * x
     | }

 

 

  • 函數

1.scala支持函數式編程,將來編寫Spark/Flink程序中,會大量使用到函數

2.函數是一個對象(變量)

3.類似於方法,函數也有輸入參數和返回值

4.函數定義不需要使用def定義

5.無需指定返回值類型

 

定義函數

語法:

val 函數變量名 = (參數名:參數類型, 參數名:參數類型....) => 函數體

例:

 val add = (x:Int, y:Int) => x + y
 add(1,2)

 

方法和函數的區別

1.方法是隸屬於類或者對象的,在運行時,它是加載到JVM的方法區中

2.可以將函數對象賦值給一個變量,在運行時,它是加載到JVM的堆內存中

3.函數是一個對象,繼承自FunctionN,函數對象有apply,curried,toString,tupled這些方法。方法則沒有

4.方法無法賦值給變量

 

方法轉換爲函數

1.有時候需要將方法轉換爲函數,作爲變量傳遞,就需要將方法轉換爲函數

2.使用_即可將方法轉換爲函數

例:

def add(x:Int,y:Int)=x+y
val a = add  _
add(1,2)

 

  • 數組

scala中,有兩種數組,一種是定長數組,另一種是變長數組

 

定長數組

1.定長數組指的是數組的長度是不允許改變的

2.數組的元素是可以改變的

3.在scala中,數組的泛型使用[]來指定

4.使用()來獲取元素

語法:

// 通過指定長度定義數組
val/var 變量名 = new Array[元素類型](數組長度)
​
// 用元素直接初始化數組
val/var 變量名 = Array(元素1, 元素2, 元素3...)

例:

val a = new Array[Int](100)
a(0) = 110
println(a(0))  

 

變長數組

1.變長數組指的是數組的長度是可變的,可以往數組中添加、刪除元素

2.創建變長數組,需要提前導入ArrayBuffer類import scala.collection.mutable.ArrayBuffer

語法:

//創建空的ArrayBuffer變長數組
import scala.collection.mutable.ArrayBuffer
val/var a = ArrayBuffer[元素類型]()

//創建帶有初始元素的ArrayBuffer
import scala.collection.mutable.ArrayBuffer
val/var a = ArrayBuffer(元素1,元素2,元素3....)

例:定義一個長度爲0的整型變長數組

val a = ArrayBuffer[Int]()

例:定義一個包含"hadoop", "storm", "spark"元素的變長數組

val a = ArrayBuffer("hadoop", "storm", "spark")

 

變長數組添加/修改/刪除元素

1.使用+=添加元素

2.使用-=刪除元素

3.使用++=追加一個數組到變長數組

例:

// 定義變長數組
import scala.collection.mutable.ArrayBuffer
val a = ArrayBuffer("hadoop", "spark", "flink")

// 追加一個元素
a += "flume"

// 刪除一個元素
 a -= "hadoop"
 
// 追加一個數組
a ++= Array("hive", "sqoop")

 

遍歷數組

1.0 until n:生成一系列的數字,包含0,不包含n

2.0 to n :包含0,也包含n

 

使用for表達式直接遍歷數組中的元素

val a = Array(1,2,3,4,5)
for(i<-a) println(i)

使用索引遍歷數組中的元素

val a = Array(1,2,3,4,5)
for(i <- 0 to a.length - 1) println(a(i))

 

數組常用算法

1.求和:sum

2.求最大值:max

3.求最小值:min

4.排序:sorted

val a = Array(1,2,3,4,5)

//求和
a.sum

//求最大值
a.max

//求最小值
a.min

//升序排序
a.sorted

//降序排序
a.sorted.reverse

 

  • 元組

元組可以用來包含一組不同類型的值。元組的元素是不可變的。

 

定義元組

語法:

//使用括號來定義元組
val/var 元組 = (元素1, 元素2, 元素3....)

//使用箭頭來定義元組(元組只有兩個元素)
val/var 元組 = 元素1->元素2

例:

val a = ("zhangsan", 20)
val b = "zhangsan" -> 20

 

訪問元組

1.使用_1、_2、_3....來訪問元組中的元素,_1表示訪問第一個元素,依次類推

例:

val a = "zhangsan" -> "male"
a._1

 

  • 列表

1.列表是scala中最重要的、也是最常用的數據結構

2.列表可以保存重複的值

3.列表有先後順序

4.在scala中,也有兩種列表,一種是不可變列表、另一種是可變列表

 

不可變列表

1.不可變集合都在immutable包中(默認導入)

語法:

val/var 變量名 = List(元素1, 元素2, 元素3...)

//使用Nil創建一個不可變的空列表
val/var 變量名 = Nil

//使用::方法創建一個不可變列表,使用::拼接方式來創建列表,必須在最後添加一個Nil
val/var 變量名 = 元素1 :: 元素2 :: Nil

例:

//創建一個不可變列表,存放以下幾個元素(1,2,3,4)
val a = List(1,2,3,4)

//使用Nil創建一個不可變的空列表
val a = Nil

//使用::方法創建列表,包含-2、-1兩個元素
val a = -2 :: -1 :: Nil

 

可變列表

1.可變列表就是列表的元素、長度都是可變的

2.要使用可變列表,先要導入import scala.collection.mutable.ListBuffer

3.可變集合都在mutable包中

語法:

//使用ListBuffer[元素類型]()創建空的可變列表
val/var 變量名 = ListBuffer[Int]()

//使用ListBuffer(元素1, 元素2, 元素3...)創建可變列表
val/var 變量名 = ListBuffer(元素1,元素2,元素3...)

例:

import scala.collection.mutable.ListBuffer

//創建空的整形可變列表
val a = ListBuffer[Int]()

//創建一個可變列表,包含以下元素:1,2,3,4
val a = ListBuffer(1,2,3,4)

 

可變列表操作

1.獲取元素(使用括號訪問(索引值))

2.添加元素(+=)

3.追加一個列表(++=)

4.更改元素(使用括號獲取元素,然後進行賦值)

5.刪除元素(-=)

6.轉換爲List(toList)

7.轉換爲Array(toArray)

例:

val a = ListBuffer(1,2,3,4)

//獲取0號索引的值
a(0)

//添加一個元素
a+=5

//追加一個列表
val b = ListBuffer(10,20,30)
a ++= b

//更改元素
a(0) = 111

//刪除元素
a -= 2

//轉換爲List(toList)
a.toList

//轉換爲Array(toArray)
a.toArray

 

列表常用操作

1.判斷列表是否爲空(isEmpty)

2.拼接兩個列表(++)

3.獲取列表的首個元素(head)和剩餘部分(tail)

4.反轉列表(reverse)

5.獲取前綴(take)、獲取後綴(drop)

6.扁平化(flaten)

7.拉鍊(zip)和拉開(unzip)

8.轉換字符串(toString)

9.生成字符串(mkString)

10.並集(union)

11.交集(intersect)

12.差集(diff)

例:

//判斷列表是否爲空
val a = List(1,2,3,4)
a.isEmpty

//拼接兩個列表
val a = List(1,2,3)
val b = List(4,5,6)
a ++ b

//獲取列表的首個元素和剩餘部分
val a = List(1,2,3)
a.head
a.tail

//反轉列表
val a = List(1,2,3)
a.reverse

//獲取列表前綴和後綴
val a = List(1,2,3,4,5)
a.take(3)
a.drop(3)

//扁平化(壓平) 扁平化表示將列表中的列表中的所有元素放到一個列表中
val a = List(List(1,2), List(3), List(4,5))
a.flatten

//拉鍊與拉開
//拉鍊:使用zip將兩個列表,組合成一個元素爲元組的列表
//拉開:將一個包含元組的列表,解開成包含兩個列表的元組
val a = List("zhangsan", "lisi", "wangwu")
val b = List(19, 20, 21)
a.zip(b)
res1.unzip

//轉換字符串 toString方法可以返回List中的所有元素
val a = List(1,2,3,4)
println(a.toString)

//生成字符串 mkString方法,可以將元素以分隔符拼接起來。默認沒有分隔符
val a = List(1,2,3,4)
a.mkString
a.mkString(":")

//並集 union表示對兩個列表取並集,不去重 可以調用distinct去重
val a1 = List(1,2,3,4)
val a2 = List(3,4,5,6)
a1.union(a2)
a1.union(a2).distinct

//交集 intersect表示對兩個列表取交集
val a1 = List(1,2,3,4)
val a2 = List(3,4,5,6)
a1.intersect(a2)

//差集 diff表示對兩個列表取差集  a1.diff(a2),表示獲取a1在a2中不存在的元素
val a1 = List(1,2,3,4)
val a2 = List(3,4,5,6)
a1.diff(a2)

 

  • Set

1.Set(集)是代表沒有重複元素的集合,元素不重複

2.不保證插入順序

3.scala中的集也分爲兩種,一種是不可變集,另一種是可變集。

 

不可變集

語法:

//創建一個空的不可變集
val/var 變量名 = Set[類型]()

//給定元素來創建一個不可變集
val/var 變量名 = Set(元素1, 元素2, 元素3...)

例:

//定義一個空的不可變集
val a = Set[Int]()

//定義一個不可變集,保存以下元素:1,1,3,2,4,8
val a = Set(1,1,3,2,4,8)

 

基本操作

1.獲取集的大小(size)

2.遍歷集(和遍歷數組一致)

3.刪除一個元素,生成一個Set(-)

4.添加一個元素,生成一個Set(+)

5.拼接兩個集,生成一個Set(++)

6.拼接集和列表,生成一個Set(++)

例:

// 創建集
val a = Set(1,1,2,3,4,5)

// 獲取集的大小
a.size

// 遍歷集
for(i <- a) println(i)

// 刪除一個元素
a - 1

//添加一個元素
a + 1

// 拼接兩個集
a ++ Set(6,7,8)

// 拼接集和列表
a ++ List(6,7,8,9)

 

可變集

可變集合不可變集的創建方式一致,只不過需要提前導入一個可變集類。手動導入:import scala.collection.mutable.Set

例:

import scala.collection.mutable.Set
val a = Set(1,2,3,4)
a += 5
a -= 1

 

  • 映射(Map)

Map可以稱之爲映射。它是由鍵值對組成的集合。在scala中,Map也分爲不可變Map和可變Map

 

不可變Map

語法:

val/var map = Map(鍵->值, 鍵->值, 鍵->值...) // 推薦,可讀性更好
val/var map = Map((鍵, 值), (鍵, 值), (鍵, 值), (鍵, 值)...)

例:

val map = Map("zhangsan"->30, "lisi"->40)
val map = Map(("zhangsan", 30), ("lisi", 30))

//根據key獲取value
map("zhangsan")

 

可變Map

定義語法與不可變Map一致。但定義可變Map需要手動導入import scala.collection.mutable.Map

例:

val map = Map("zhangsan"->30, "lisi"->40)

 

Map基本操作

1.獲取值(map(key))

2.獲取所有key(map.keys)

3.獲取所有value(map.values)

4.遍歷map集合

5.找到指定鍵的值如果不存在返回指定值(getOrElse)

6.增加key,value對(+)

7.刪除key(-)

例:

 val map = Map("zhangsan"->30, "lisi"->40)
 
//獲取zhagnsan的年齡
map("zhangsan")
 
//獲取所有的key
map.keys
  
//獲取所有的value
map.values
  
//遍歷打印所有的key value
for((x,y) <- map) println(s"${x} ${y}")
  
//獲取wangwu的年齡,如果wangwu不存在,則返回-1
map.getOrElse("wangwu", -1)
  
//新增一個學生:wangwu, 35
map += "wangwu"->35
  
//將lisi從可變映射中移除
map - "lisi"

 

  • iterator迭代器

1.scala針對每一類集合都提供了一個迭代器(iterator)用來迭代訪問集合

2.使用iterator方法可以從集合獲取一個迭代器

3.迭代器的兩個基本操作

4.hasNext——查詢容器中是否有下一個元素

5.next——返回迭代器的下一個元素,如果沒有,拋出NoSuchElementException

6.每一個迭代器都是有狀態的

7.迭代完後保留在最後一個元素的位置

8.再次使用則拋出NoSuchElementException

9.可以使用while或者for來逐個返回元素

例:

//定義一個列表,包含以下元素:1,2,3,4,5
var a = List(1,2,3,4,5)

//創建迭代器
val ite = a.iterator

//使用while循環和迭代器,遍歷打印該列表
while(ite.hasNext) {
println(ite.next)
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章