變量
聲明變量
val/var 變量標(biāo)識:變量類型 = 初始值
其中
- Val表示的是不可改變的變量
- Var表示的是可以重新賦值的變量
Notice:
變量寫在變量名后面蕾各,且不用寫分號
語法格式
val name: String = "hello world"
var age:Int = 18
使用Scala中的類型推導(dǎo)
Scala比Java語言更加簡潔,類似于Js庆揪,類型可以被變量自動根據(jù)等號后面的值來推導(dǎo)
語法格式
val name = "leon"
//可以自動推導(dǎo)出name的類型為String式曲,不用再手動添加
惰性賦值
類似于懶加載,變量不會一次性全部加載到JVM的內(nèi)存中,可以提高運(yùn)行效率
語法格式
lazy val/var 變量名 = 表達(dá)式
lazy val sql =
"""insert overwrite table adm.itcast_adm_personas 19
| select | a.user_id, .... | left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id | left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id;"""
sql: String = <lazy>
字符串
使用字符串
語法格式
val/var 變量名 = “字符串”
有一個(gè)人的名字叫"hadoop"吝羞,請打印他的名字以及名字的長度兰伤。
val name = "liming"
println(name + name.length)
//打印"liming6"
使用插值表達(dá)式
語法格式
val/var 變量名 = s"${變量/表達(dá)式}字符串"
Tips:
- 在定義字符串之前添加 s
- 在字符串中,可以使用 ${} 來引用變量或者編寫表達(dá)式
請定義若干個(gè)變量钧排,分別保存:"zhangsan"敦腔、30、"male"恨溜,定義一個(gè)字符串符衔,保存這些信息。
打印輸出:name=zhangsan, age=30, sex=male
scala> val name = "zhangsan"
name: String = zhangsan
scala> val age = 30
age: Int = 30
scala> val sex = "male"
sex: String = male
scala> val info = s"name=${name}, age=${age}, sex=${sex}"
info: String = name=zhangsan, age=30, sex=male
scala> println(info)
name=zhangsan, age=30, sex=male
使用三引號
語法
val/var 變量名 = """字符串1
字符串2"""
定義一個(gè)字符串糟袁,保存以下SQL語句
select
*
from
t_user
where
name = "zhangsan"
val sql = """select
| *
| from
| t_user
| where
| name = "zhangsan""""
println(sql)
數(shù)據(jù)類型與操作符
基本數(shù)據(jù)類型
基礎(chǔ)類型 | 類型說明 |
---|---|
Byte | 8位帶符號整數(shù) |
Short | 16位帶符號整數(shù) |
Int | 32位帶符號整數(shù) |
Long | 64位帶符號整數(shù) |
Char | 16位無符號Unicode字符 |
String | Char類型的序列(字符串) |
Float | 32位單精度浮點(diǎn)數(shù) |
Double | 64位雙精度浮點(diǎn)數(shù) |
Boolean | true或false |
Tips:
- scala中所有的類型都使用大寫字母開頭
- 整形使用 Int 而不是Integer
- scala中定義變量可以不寫類型判族,讓scala編譯器自動推斷
操作符
類別 | 操作符 |
---|---|
算術(shù)運(yùn)算符 | +、-系吭、*五嫂、/ |
關(guān)系運(yùn)算符 | >颗品、<肯尺、==、!=躯枢、>=则吟、<= |
邏輯運(yùn)算符 | &&、|| 锄蹂、氓仲! |
位運(yùn)算符 | &、||得糜、^ 敬扛、<<、>> |
Tips
scala中沒有朝抖,++啥箭、--運(yùn)算符
-
與Java不一樣,在scala中治宣,可以直接使用 == 急侥、 != 進(jìn)行比較,它們與 equals 方法表示一
致侮邀。而比較兩個(gè)對象的引用值坏怪,使用
eq
有一個(gè)字符串"abc",再創(chuàng)建第二個(gè)字符串绊茧,值為:在第一個(gè)字符串后拼接一個(gè)空字符串铝宵。
然后使用比較這兩個(gè)字符串是否相等、再查看它們的引用值是否相等华畏。
val str1 = "abc"
val str2 = str1 + ""
str1 == str2 //true
str1.eq(str2) //false
scala類型層次結(jié)構(gòu)
![類型 | 說明 |
---|---|
Any | 所有類型的父類捉超,,它有兩個(gè)子類AnyRef與AnyVal |
AnyVal | 所有數(shù)值類型的父類 |
AnyRef | 所有對象類型(引用類型)的父類 |
Unit | 表示空胧卤,Unit是AnyVal的子類,它只有一個(gè)的實(shí)例() 它類似于Java中的void拼岳,但scala要比Java更加面向?qū)ο?/td> |
Null | Null是AnyRef的子類枝誊,也就是說它是所有引用類型的子類。它的實(shí)例是null 可以將null賦值給任何對象類型 |
Nothing | 所有類型的子類 不能直接創(chuàng)建該類型實(shí)例惜纸,某個(gè)方法拋出異常時(shí)叶撒,返回的就是Nothing類型因?yàn)镹othing是所有類的子類,那么它可以賦值為任何類型 |
條件表達(dá)式
Tips:
- 在scala中耐版,條件表達(dá)式也是有返回值的
- 在scala中祠够,沒有三元表達(dá)式,可以使用if表達(dá)式替代三元表達(dá)式
定義一個(gè)變量sex粪牲,再定義一個(gè)result變量古瓤,如果等于male,result等于1腺阳,如果result等于0
scala> val sex = "male"
sex: String = male
scala> val result = if(sex == "male") 1 else 0
result: Int = 1
塊表達(dá)式
scala中落君,使用{}表示一個(gè)塊表達(dá)式
和if表達(dá)式一樣,塊表達(dá)式也是有值的
值就是最后一個(gè)表達(dá)式的值
scala> val a = {
| println("1 + 1")
| 1 + 1
| }
循環(huán)
for
? 語法
for(i <- 表達(dá)式/數(shù)組/集合) {
// 表達(dá)式
}
- 使用for表達(dá)式打印1-10的數(shù)字
//先定義一個(gè)nums
scala> val nums = 1.to(10)
nums: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//然后再打印for循環(huán)
scala> for(i <- nums) println(i)
- 中綴法
// 中綴調(diào)用法
scala> for(i <- 1 to 10) println(i)
嵌套循環(huán)
? 使用for表達(dá)式亭引,打印以下字符
*****
*****
*****
步驟
是否for表達(dá)式打印3行绎速,5列星星
每打印5個(gè)星星,換行
for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")}
scala中可以把嵌套寫成在一個(gè)括號中執(zhí)行焙蚓。然后后面接條件表達(dá)式
守衛(wèi)
? for表達(dá)式中纹冤,可以添加if判斷語句,這個(gè)if判斷就稱之為守衛(wèi)购公。我們可以使用守衛(wèi)讓for表達(dá)式更簡
潔萌京。
語法
for(i <- 表達(dá)式/數(shù)組/集合 if 表達(dá)式) {
? // 表達(dá)式
}
使用for表達(dá)式打印能夠整除3的數(shù)字
// 添加守衛(wèi),打印能夠整除3的數(shù)字
for(i <- 1 to 10 if i % 3 == 0) println(i)
for推導(dǎo)式
將來可以使用for推導(dǎo)式生成一個(gè)新的集合(一組數(shù)據(jù))
-
在for循環(huán)體中宏浩,可以使用yield表達(dá)式構(gòu)建出一個(gè)集合知残,我們把使用yield的for表達(dá)式稱之為推
導(dǎo)式
生成一個(gè)10、20绘闷、30...100的集合
// for推導(dǎo)式:for表達(dá)式中以yield開始橡庞,該for表達(dá)式會構(gòu)建出一個(gè)集合
val v = for(i <- 1 to 10) yield i * 10
while循環(huán)
scala中while循環(huán)和Java中是一致的
打印1-10的數(shù)字
scala> var i = 1 i:
Int = 1
scala> while(i <= 10) {
| println(i)
| i = i+1
| }
方法
基本定義
? 一個(gè)類可以有自己的方法,scala中的方法和Java方法類似印蔗。但scala與Java定義方法的語法是不一
樣的扒最,而且scala支持多種調(diào)用方式。
語法設(shè)置
def methodName (參數(shù)名:參數(shù)類型, 參數(shù)名:參數(shù)類型) : [return type] = {
? // 方法體:一系列的代碼
}
Tips:
- 參數(shù)列表的參數(shù)類型不能省略
- 返回值類型可以省略
- 返回值可以不寫return华嘹,默認(rèn)就是{}塊表達(dá)式的值
示例
定義一個(gè)方法吧趣,實(shí)現(xiàn)兩個(gè)整形數(shù)值相加,返回相加后的結(jié)果
調(diào)用該方法
scala> def add(x:Int, y:Int):Int = x * y
m1: (x: Int, y: Int)Int
scala> add(1,2)
res10: Int = 2
方法參數(shù)
? scala中的方法參數(shù),使用比較靈活强挫。它支持以下幾種類型的參數(shù):
- 默認(rèn)參數(shù)
- 帶名參數(shù)
- 變長參數(shù)
默認(rèn)參數(shù)
? 在定義方法時(shí)可以給參數(shù)定義一個(gè)默認(rèn)值岔霸。
示例
定義一個(gè)計(jì)算兩個(gè)值相加的方法,這兩個(gè)值默認(rèn)為0
調(diào)用該方法俯渤,不傳任何參數(shù)
// x呆细,y帶有默認(rèn)值為0
def add(x:Int = 0, y:Int = 0) = x + y
add()
帶名參數(shù)
? 在調(diào)用方法時(shí),可以指定參數(shù)的名稱來進(jìn)行調(diào)用八匠。
示例
定義一個(gè)計(jì)算兩個(gè)值相加的方法絮爷,這兩個(gè)值默認(rèn)為0
調(diào)用該方法,只設(shè)置第一個(gè)參數(shù)的值
def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)
變長參數(shù)
? 如果方法的參數(shù)是不固定的梨树,可以定義一個(gè)方法的參數(shù)是變長參數(shù)坑夯。
語法格式:
def 方法名(參數(shù)名:參數(shù)類型*):返回值類型 = {
? 方法體
}
Tips:
- 在參數(shù)類型后面加一個(gè) * 號,表示參數(shù)可以是0個(gè)或者多個(gè)
示例
定義一個(gè)計(jì)算若干個(gè)值相加的方法
調(diào)用方法抡四,傳入以下數(shù)據(jù):1,2,3,4,5
scala> def add(num:Int*) = num.sum
add: (num: Int*)Int
scala> add(1,2,3,4,5)
res1: Int = 15
方法返回值類型推斷
? scala定義方法可以省略返回值柜蜈,由scala自動推斷返回值類型。這樣方法定義后更加簡潔指巡。
示例
使用類型推斷重新定義上面的add方法
scala> def add(x:Int, y:Int) = x + y
add: (x: Int, y: Int)Int
scala> add(1,2)
res12: Int = 3
方法調(diào)用方式
后綴調(diào)用法
語法
對象名.方法名(參數(shù))
示例
使用后綴法 Math.abs 求絕對值
scala> Math.abs(-1)
res3: Int = 1
中綴調(diào)用法
語法
對象名 方法名 參數(shù)
例如 : 1 to 10
示例
使用中綴法 Math.abs 求絕對值
scala> Math abs -1
res4: Int = 1
花括號調(diào)用法
語法
Math.abs{
? // 表達(dá)式1
? // 表達(dá)式2
}
示例
使用花括號調(diào)用法 Math.abs 求絕對值
scala> Math.abs{-10}
res13: Int = 10
無括號調(diào)用法
如果方法沒有參數(shù)淑履,可以省略方法名后面的括號
示例
- 定義一個(gè)無參數(shù)的方法,打印"hello"
- 使用無括號調(diào)用法調(diào)用該方法
def m3()=println("hello")
m3()
函數(shù)
scala支持函數(shù)式編程厌处,將來編寫Spark/Flink程序中鳖谈,會大量經(jīng)常使用到函數(shù)
定義函數(shù)
語法
val 函數(shù)變量名 = (參數(shù)名:參數(shù)類型, 參數(shù)名:參數(shù)類型....) => 函數(shù)體
Tips:
- 函數(shù)是一個(gè)對象(變量)
- 類似于方法岁疼,函數(shù)也有輸入?yún)?shù)和返回值
- 函數(shù)定義不需要使用 def 定義
- 無需指定返回值類型
示例
定義一個(gè)兩個(gè)數(shù)值相加的函數(shù)
調(diào)用該函數(shù)
scala> val add = (x:Int, y:Int) => x + y
add: (Int, Int) => Int = <function2>
scala> add(1,2)
res3: Int = 3
方法和函數(shù)的區(qū)別
方法是隸屬于類或者對象的阔涉,在運(yùn)行時(shí),它是加載到JVM的方法區(qū)中
可以將函數(shù)對象賦值給一個(gè)變量捷绒,在運(yùn)行時(shí)瑰排,它是加載到JVM的堆內(nèi)存中
-
函數(shù)是一個(gè)對象,繼承自FunctionN暖侨,函數(shù)對象有apply椭住,curried,toString字逗,tupled這些方
法京郑。方法則沒有
示例
方法無法賦值給變量
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add
<console>:12: error: missing argument list for method add Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.
val a = add
方法轉(zhuǎn)換為函數(shù)
- 有時(shí)候需要將方法轉(zhuǎn)換為函數(shù),作為變量傳遞葫掉,就需要將方法轉(zhuǎn)換為函數(shù)
- 使用
_
即可將方法轉(zhuǎn)換為函數(shù)
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int scala>
val a = add _
a: (Int, Int) => Int = <function2>