Hadoop(二十三)scala基礎(chǔ)

1.1. 什么是Scala

Scala是一種多范式的編程語言褥赊,其設(shè)計的初衷是要集成面向?qū)ο缶幊毯秃瘮?shù)式編程的各種特性登馒。Scala運(yùn)行于Java平臺(Java虛擬機(jī))式曲,并兼容現(xiàn)有的Java程序。[圖片上傳失敗...(image-c23538-1527488548129)]

1.2. 為什么要學(xué)Scala

1.優(yōu)雅:這是框架設(shè)計師第一個要考慮的問題发笔,框架的用戶是應(yīng)用開發(fā)程序員盟萨,API是否優(yōu)雅直接影響用戶體驗(yàn)。

2.速度快:Scala語言表達(dá)能力強(qiáng)了讨,一行代碼抵得上Java多行捻激,開發(fā)速度快;Scala是靜態(tài)編譯的前计,所以和JRuby,Groovy比起來速度會快很多胞谭。

  1. 能融合到Hadoop生態(tài)圈:Hadoop現(xiàn)在是大數(shù)據(jù)事實(shí)標(biāo)準(zhǔn),Spark并不是要取代Hadoop男杈,而是要完善Hadoop生態(tài)丈屹。JVM語言大部分可能會想到Java,但Java做出來的API太丑伶棒,或者想實(shí)現(xiàn)一個優(yōu)雅的API太費(fèi)勁旺垒。

[圖片上傳失敗...(image-b141d4-1527488548129)]

2. Scala編譯器安裝

2.1. 安裝JDK

因?yàn)镾cala是運(yùn)行在JVM平臺上的,所以安裝Scala之前要安裝JDK

2.2. 安裝Scala

2.2.1. Windows安裝Scala編譯器

訪問Scala官網(wǎng)http://www.scala-lang.org/下載Scala編譯器安裝包肤无,目前最新版本是2.12.x先蒋,但是目前大多數(shù)的框架都是用2.10.x編寫開發(fā)的,所以這里推薦2.10.x版本宛渐,下載scala-2.10.6.msi后點(diǎn)擊下一步就可以了

2.2.2. Linux安裝Scala編譯器

下載Scala地址http://downloads.typesafe.com/scala/2.10.6/scala-2.10.6.tgz然后解壓Scala到指定目錄

tar -zxvf scala-2.10.6.tgz -C /usr/java

配置環(huán)境變量竞漾,將scala加入到PATH中

vi /etc/profile

export JAVA_HOME=/usr/java/jdk1.7.0_45

export PATH=$PATH:$JAVA_HOME/bin:/usr/java/scala-2.10.6/bin

2.2.3. Scala開發(fā)工具安裝

目前Scala的開發(fā)工具主要有兩種:Eclipse和IDEA眯搭,這兩個開發(fā)工具都有相應(yīng)的Scala插件,如果使用Eclipse业岁,直接到Scala官網(wǎng)下載即可http://scala-ide.org/download/sdk.html坦仍。

由于IDEA的Scala插件更優(yōu)秀,大多數(shù)Scala程序員都選擇IDEA叨襟,可以到http://www.jetbrains.com/idea/download/下載社區(qū)免費(fèi)版,點(diǎn)擊下一步安裝即可幔荒,安裝時如果有網(wǎng)絡(luò)可以選擇在線安裝Scala插件糊闽。這里我們使用離線安裝Scala插件:

1.安裝IDEA,點(diǎn)擊下一步即可爹梁。由于我們離線安裝插件右犹,所以點(diǎn)擊Skip All and Set Defaul

2.下載IEDA的scala插件,地址http://plugins.jetbrains.com/?idea_ce

[圖片上傳失敗...(image-395c8d-1527488548129)]

3.安裝Scala插件:Configure -> Plugins -> Install plugin from disk -> 選擇Scala插件 -> OK -> 重啟IDEA

[圖片上傳失敗...(image-e87daf-1527488548129)]

[圖片上傳失敗...(image-fe195c-1527488548129)]

[圖片上傳失敗...(image-1dd0dd-1527488548129)]

[圖片上傳失敗...(image-b0367d-1527488548129)]

3. Scala基礎(chǔ)

3.1. 聲明變量

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/6.

/ object VariableDemo { def main(args: Array[String]) { //使用val定義的變量值是不可變的姚垃,相當(dāng)于java里用final修飾的變量 val i = 1 //使用var定義的變量是可變得念链,在Scala中鼓勵使用val var s = "hello" //Scala編譯器會自動推斷變量的類型,必要的時候可以指定類型</pre>

<pre style="mso-pagination:widow-orphan;background:white"> //變量名在前积糯,類型在后 val str: String = "itcast" }

}</pre>

|

3.2. 常用類型

Scala和Java一樣掂墓,有7種數(shù)值類型Byte、Char看成、Short君编、Int、Long川慌、Float和Double(無包裝類型)和一個Boolean類型

3.3. 條件表達(dá)式

Scala的的條件表達(dá)式比較簡潔吃嘿,例如:

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/7.

/ object ConditionDemo { def main(args: Array[String]) { val x = 1 //判斷x的值,將結(jié)果賦給y val y = if (x > 0) 1 else -1 //打印y的值 println(y) //支持混合類型表達(dá)式 val z = if (x > 1) 1 else "error" //打印z的值 println(z) //如果缺失else梦重,相當(dāng)于if (x > 2) 1 else () val m = if (x > 2) 1 println(m) //在scala中每個表達(dá)式都有值兑燥,scala中有個Unit類,寫做(),相當(dāng)于Java中的void val n = if (x > 2) 1 else ()

println(n) //if和else if val k = if (x < 0) 0 else if (x >= 1) 1 else -1 println(k)

}

}</pre>

|

3.4. 塊表達(dá)式

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/7.

/ object BlockExpressionDemo { def main(args: Array[String]) { val x = 0 //在scala中{}中課包含一系列表達(dá)式琴拧,塊中最后一個表達(dá)式的值就是塊的值 //下面就是一個塊表達(dá)式 val result = { if (x < 0){

-1 } else if(x >= 1) { 1 } else { "error" }

} //result的值就是塊表達(dá)式的結(jié)果 println(result)

}

}</pre>

|

3.5. 循環(huán)

在scala中有for循環(huán)和while循環(huán)降瞳,用for循環(huán)比較多

<pre style="mso-pagination:widow-orphan;background:white">for循環(huán)語法結(jié)構(gòu):for (i <- 表達(dá)式/數(shù)組/集合)</pre>

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/7.

/ object ForDemo { def main(args: Array[String]) { //for(i <- 表達(dá)式),表達(dá)式1 to 10返回一個Range(區(qū)間)</pre>

<pre style="mso-pagination:widow-orphan;background:white"> //每次循環(huán)將區(qū)間中的一個值賦給i for (i <- 1 to 10)

println(i) //for(i <- 數(shù)組) val arr = Array("a", "b", "c") for (i <- arr)

println(i) //高級for循環(huán) //每個生成器都可以帶一個條件,注意:if前面沒有分號 for(i <- 1 to 3; j <- 1 to 3 if i != j)

print((10 * i + j) + " ")

println() //for推導(dǎo)式:如果for循環(huán)的循環(huán)體以yield開始蚓胸,則該循環(huán)會構(gòu)建出一個集合</pre>

<pre style="mso-pagination:widow-orphan;background:white"> //每次迭代生成集合中的一個值 val v = for (i <- 1 to 10) yield i * 10 println(v)

}

}</pre>

|

3.6. 調(diào)用方法和函數(shù)

Scala中的+ - * / %等操作符的作用與Java一樣力崇,位操作符 & | ^ >> <<也一樣。只是有

一點(diǎn)特別的:這些操作符實(shí)際上是方法赢织。例如:

a + b

是如下方法調(diào)用的簡寫:

a.+(b)

a 方法 b可以寫成 a.方法(b)

3.7. 定義方法和函數(shù)

3.7.1. 定義方法

[圖片上傳失敗...(image-a6b603-1527488548129)]

方法的返回值類型可以不寫亮靴,編譯器可以自動推斷出來,但是對于遞歸函數(shù)于置,必須指定返回類型

3.7.2. 定義函數(shù)

[圖片上傳失敗...(image-c00ef5-1527488548129)]

3.7.3. 方法和函數(shù)的區(qū)別

在函數(shù)式編程語言中茧吊,函數(shù)是“頭等公民”贞岭,它可以像任何其他數(shù)據(jù)類型一樣被傳遞和操作

案例:首先定義一個方法,再定義一個函數(shù)搓侄,然后將函數(shù)傳遞到方法里面

[圖片上傳失敗...(image-d79b3a-1527488548129)]

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/11.

/ object MethodAndFunctionDemo { //定義一個方法 //方法m2參數(shù)要求是一個函數(shù)瞄桨,函數(shù)的參數(shù)必須是兩個Int類型</pre>

<pre style="mso-pagination:widow-orphan;background:white"> //返回值類型也是Int類型 def m1(f: (Int, Int) => Int) : Int = {

f(2, 6)

} //定義一個函數(shù)f1,參數(shù)是兩個Int類型讶踪,返回值是一個Int類型 val f1 = (x: Int, y: Int) => x + y //再定義一個函數(shù)f2 val f2 = (m: Int, n: Int) => m * n //main方法 def main(args: Array[String]) { //調(diào)用m1方法芯侥,并傳入f1函數(shù) val r1 = m1(f1)

println(r1) //調(diào)用m1方法,并傳入f2函數(shù) val r2 = m1(f2)

println(r2)

}

}</pre>

|

3.7.4. 將方法轉(zhuǎn)換成函數(shù)(神奇的下劃線)

[圖片上傳失敗...(image-ddfd28-1527488548129)]

4. 數(shù)組乳讥、映射柱查、元組、集合

4.1. 數(shù)組

4.1.1. 定長數(shù)組和變長數(shù)組

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala import scala.collection.mutable.ArrayBuffer /*

  • Created by ZX on 2015/11/11.

/ object ArrayDemo { def main(args: Array[String]) { //初始化一個長度為8的定長數(shù)組云石,其所有元素均為0 val arr1 = new ArrayInt //直接打印定長數(shù)組唉工,內(nèi)容為數(shù)組的hashcode值 println(arr1) //將數(shù)組轉(zhuǎn)換成數(shù)組緩沖汹忠,就可以看到原數(shù)組中的內(nèi)容了 //toBuffer會將數(shù)組轉(zhuǎn)換長數(shù)組緩沖 println(arr1.toBuffer) //注意:如果new淋硝,相當(dāng)于調(diào)用了數(shù)組的apply方法,直接為數(shù)組賦值 //初始化一個長度為1的定長數(shù)組 val arr2 = ArrayInt

println(arr2.toBuffer) //定義一個長度為3的定長數(shù)組 val arr3 = Array("hadoop", "storm", "spark") //使用()來訪問元素 println(arr3(2)) *//////////////////////////////////////////////////

//變長數(shù)組(數(shù)組緩沖) //如果想使用數(shù)組緩沖宽菜,需要導(dǎo)入import scala.collection.mutable.ArrayBuffer包val ab = ArrayBufferInt //向數(shù)組緩沖的尾部追加一個元素 //+=尾部追加元素* ab += 1 //追加多個元素 ab += (2, 3, 4, 5) //追加一個數(shù)組++= ab ++= Array(6, 7) //追加一個數(shù)組緩沖 ab ++= ArrayBuffer(8,9) //*打印數(shù)組緩沖ab

//在數(shù)組某個位置插入元素用insert* ab.insert(0, -1, 0) //刪除數(shù)組某個位置的元素用remove ab.remove(8, 2)

println(ab)

}

}</pre>

|

4.1.2. 遍歷數(shù)組

1.增強(qiáng)for循環(huán)

2.好用的until會生成腳標(biāo)谣膳,0 until 10 包含0不包含10

[圖片上傳失敗...(image-7d32da-1527488548119)]

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/12.

/ object ForArrayDemo { def main(args: Array[String]) { //初始化一個數(shù)組 val arr = Array(1,2,3,4,5,6,7,8) //增強(qiáng)for循環(huán) for(i <- arr)

println(i) //*好用的until會生成一個Range

//reverse是將前面生成的Range反轉(zhuǎn)* for(i <- (0 until arr.length).reverse)

println(arr(i))

}

}</pre>

|

4.1.3. 數(shù)組轉(zhuǎn)換

yield關(guān)鍵字將原始的數(shù)組進(jìn)行轉(zhuǎn)換會產(chǎn)生一個新的數(shù)組,原始的數(shù)組不變

[圖片上傳失敗...(image-6a6e95-1527488548119)]

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/12.

/ object ArrayYieldDemo { def main(args: Array[String]) { //定義一個數(shù)組 val arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9) //將偶數(shù)取出乘以10后再生成一個新的數(shù)組 val res = for (e <- arr if e % 2 == 0) yield e * 10 println(res.toBuffer) //更高級的寫法,用著更爽 //filter是過濾铅乡,接收一個返回值為boolean的函數(shù) //map相當(dāng)于將數(shù)組中的每一個元素取出來参歹,應(yīng)用傳進(jìn)去的函數(shù) val r = arr.filter(_ % 2 == 0).map(_ * 10)

println(r.toBuffer)

}

}</pre>

|

4.1.4. 數(shù)組常用算法

在Scala中,數(shù)組上的某些方法對數(shù)組進(jìn)行相應(yīng)的操作非常方便隆判!

[圖片上傳失敗...(image-6ebce7-1527488548119)]

4.2. 映射

在Scala中犬庇,把哈希表這種數(shù)據(jù)結(jié)構(gòu)叫做映射

4.2.1. 構(gòu)建映射

[圖片上傳失敗...(image-3ef147-1527488548119)]

4.2.2. 獲取和修改映射中的值

[圖片上傳失敗...(image-1ff9aa-1527488548119)]

好用的getOrElse

[圖片上傳失敗...(image-903ef4-1527488548119)]

注意:在Scala中,有兩種Map侨嘀,一個是immutable包下的Map臭挽,該Map中的內(nèi)容不可變;另一個是mutable包下的Map咬腕,該Map中的內(nèi)容可變

例子:

[圖片上傳失敗...(image-9de60c-1527488548119)]

注意:通常我們在創(chuàng)建一個集合是會用val這個關(guān)鍵字修飾一個變量(相當(dāng)于java中的final)欢峰,那么就意味著該變量的引用不可變,該引用中的內(nèi)容是不是可變涨共,取決于這個引用指向的集合的類型

4.3. 元組

映射是K/V對偶的集合纽帖,對偶是元組的最簡單形式,元組可以裝著多個不同類型的值举反。

4.3.1. 創(chuàng)建元組

[圖片上傳失敗...(image-fae745-1527488548119)]

4.3.2. 獲取元組中的值

[圖片上傳失敗...(image-535291-1527488548119)]

4.3.3. 將對偶的集合轉(zhuǎn)換成映射

[圖片上傳失敗...(image-fee793-1527488548119)]

4.3.4. 拉鏈操作

zip命令可以將多個值綁定在一起

[圖片上傳失敗...(image-e37f23-1527488548119)]

注意:如果兩個數(shù)組的元素個數(shù)不一致懊直,拉鏈操作后生成的數(shù)組的長度為較小的那個數(shù)組的元素個數(shù)

4.4. 集合

Scala的集合有三大類:序列Seq、集Set火鼻、映射Map室囊,所有的集合都擴(kuò)展自Iterable特質(zhì)

在Scala中集合有可變(mutable)和不可變(immutable)兩種類型雕崩,immutable類型的集合初始化后就不能改變了(注意與val修飾的變量進(jìn)行區(qū)別)

4.4.1. 序列

不可變的序列 import scala.collection.immutable._

在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。

9 :: List(5, 2) :: 操作符是將給定的頭和尾創(chuàng)建一個新的列表

注意::: 操作符是右結(jié)合的融撞,如9 :: 5 :: 2 :: Nil相當(dāng)于 9 :: (5 :: (2 :: Nil))

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.collect object ImmutListDemo { def main(args: Array[String]) { //創(chuàng)建一個不可變的集合 val lst1 = List(1,2,3) //將0插入到lst1的前面生成一個新的List val lst2 = 0 :: lst1 val lst3 = lst1.::(0) val lst4 = 0 +: lst1 val lst5 = lst1.+:(0) //將一個元素添加到lst1的后面產(chǎn)生一個新的集合 val lst6 = lst1 :+ 3 val lst0 = List(4,5,6) //將2個list合并成一個新的List val lst7 = lst1 ++ lst0 //將lst1插入到lst0前面生成一個新的集合 val lst8 = lst1 ++: lst0 //將lst0插入到lst1前面生成一個新的集合 val lst9 = lst1.:::(lst0)

println(lst9)

}

}</pre>

|

可變的序列 import scala.collection.mutable._

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.collect import scala.collection.mutable.ListBuffer object MutListDemo extends App{ //構(gòu)建一個可變列表盼铁,初始有3個元素1,2,3 val lst0 = ListBufferInt //創(chuàng)建一個空的可變列表 val lst1 = new ListBuffer[Int] //向lst1中追加元素,注意:沒有生成新的集合 lst1 += 4 lst1.append(5) //將lst1中的元素最近到lst0中尝偎, 注意:沒有生成新的集合 lst0 ++= lst1 //將lst0和lst1合并成一個新的ListBuffer 注意:生成了一個集合 val lst2= lst0 ++ lst1 //將元素追加到lst0的后面生成一個新的集合 val lst3 = lst0 :+ 5 }</pre>

|

4.5. Set

不可變的Set

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.collect import scala.collection.immutable.HashSet object ImmutSetDemo extends App{ val set1 = new HashSetInt //將元素和set1合并生成一個新的set饶火,原有set不變 val set2 = set1 + 4 //set中元素不能重復(fù) val set3 = set1 ++ Set(5, 6, 7) val set0 = Set(1,3,4) ++ set1 println(set0.getClass)

}</pre>

|

可變的Set

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.collect import scala.collection.mutable object MutSetDemo extends App{ //創(chuàng)建一個可變的HashSet val set1 = new mutable.HashSetInt //向HashSet中添加元素 set1 += 2 //add等價于+= set1.add(4) set1 ++= Set(1,3,5)

println(set1) //刪除一個元素 set1 -= 5 set1.remove(2)

println(set1)

}</pre>

|

4.6. Map

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.collect import scala.collection.mutable object MutMapDemo extends App{ val map1 = new mutable.HashMapString, Int //向map中添加數(shù)據(jù) map1("spark") = 1 map1 += (("hadoop", 2)) map1.put("storm", 3)

println(map1) //從map中移除元素 map1 -= "spark" map1.remove("hadoop")

println(map1)

}</pre>

|

5. 類、對象致扯、繼承肤寝、特質(zhì)

Scala的類與Java、C++的類比起來更簡潔急前,學(xué)完之后你會更愛Scala!F俟埂裆针!

5.1. 類

5.1.1. 類的定義

|

<pre style="mso-pagination:widow-orphan;background:white">//在Scala中,類并不用聲明為public寺晌。</pre>

<pre style="mso-pagination:widow-orphan;background:white">//Scala源文件中可以包含多個類世吨,所有這些類都具有公有可見性。 class Person { //用val修飾的變量是只讀屬性呻征,有g(shù)etter但沒有setter</pre>

<pre style="mso-pagination:widow-orphan;background:white"> //(相當(dāng)與Java中用final修飾的變量) val id = "9527" </pre>

<pre style="mso-pagination:widow-orphan;background:white">//用var修飾的變量既有g(shù)etter又有setter var age: Int = 18</pre>

<pre style="mso-pagination:widow-orphan;background:white">//類私有字段,只能在類的內(nèi)部使用private var name: String = "****唐伯虎" //對象私有字段,訪問權(quán)限更加嚴(yán)格的耘婚,Person類的方法只能訪問到當(dāng)前對象的字段 private[this] val pet = "****小強(qiáng)"</pre>

<pre style="mso-pagination:widow-orphan;background:white">}</pre>

|

5.1.2. 構(gòu)造器

注意:主構(gòu)造器會執(zhí)行類定義中的所有語句

|

<pre style="mso-pagination:widow-orphan;background:white">/*

每個類都有主構(gòu)造器,主構(gòu)造器的參數(shù)直接放置類名后面陆赋,與類交織在一起 / class Student(val* name: String, val age: Int){ //主構(gòu)造器會執(zhí)行類定義中的所有語句 println("****執(zhí)行主構(gòu)造器") try {

println("****讀取文件") throw new IOException("io exception")

} catch { case e: NullPointerException => println("****打印異常Exception : " + e) case e: IOException => println("****打印異常Exception : " + e)

} finally {

println("****執(zhí)行finally部分")

} private var gender = "male" //用this關(guān)鍵字定義輔助構(gòu)造器 def this(name: String, age: Int, gender: String){ //每個輔助構(gòu)造器必須以主構(gòu)造器或其他的輔助構(gòu)造器的調(diào)用開始</pre>

<pre style="mso-pagination:widow-orphan;background:white"> this(name, age)

println("****執(zhí)行輔助構(gòu)造器") this.gender = gender

}

}</pre>

|

|

<pre style="mso-pagination:widow-orphan;background:white">/*

**構(gòu)造器參數(shù)可以不帶val或var沐祷,如果不帶val或var的參數(shù)至少被一個方法所使用,</pre>

<pre style="mso-pagination:widow-orphan;background:white"> ****那么它將會被提升為字段 /</pre>

<pre style="mso-pagination:widow-orphan;background:white">//在類名后面加private就變成了私有的 class Queen private(val name: String, prop: Array[String], private var age: Int = 18){

println(prop.size) //prop*被下面的方法使用后攒岛,prop就變成了不可變得對象私有字段赖临,等同于private[this] val prop

//如果沒有被方法使用該參數(shù)將不被保存為字段,僅僅是一個可以被主構(gòu)造器中的代碼訪問的普通參數(shù)* def description = name + " is " + age + " years old with " + prop.toBuffer

} object Queen{ def main(args: Array[String]) {

//私有的構(gòu)造器灾锯,只有在其伴生對象中使用 val q = new Queen("hatano", Array("****蠟燭", "****皮鞭"), 20)

println(q.description())

}

}</pre>

|

5.2. 對象

5.2.1. 單例對象

在Scala中沒有靜態(tài)方法和靜態(tài)字段兢榨,但是可以使用object這個語法結(jié)構(gòu)來達(dá)到同樣的目的

1.存放工具方法和常量

2.高效共享單個不可變的實(shí)例

3.單例模式

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala import scala.collection.mutable.ArrayBuffer /*

  • Created by ZX on 2015/11/14.

/ object SingletonDemo { def main(args: Array[String]) { //單例對象,不需要new顺饮,用【類名.方法】調(diào)用對象中的方法 val session = SessionFactory.getSession() println(session)

}

} object SessionFactory{ //該部分相當(dāng)于java中的靜態(tài)塊 var counts = 5 val sessions = new ArrayBufferSession while(counts > 0){ sessions += new Session counts -= 1 } //在object中的方法相當(dāng)于java中的靜態(tài)方法 def getSession(): Session ={ sessions.remove(0)

}

} class Session{

}</pre>

|

5.2.2. 伴生對象

在Scala的類中吵聪,與類名相同的對象叫做伴生對象,類和伴生對象之間可以相互訪問私有的方法和屬性

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/14.

/ class Dog { val id = 1 private var name = "itcast" def printName(): Unit ={ //在Dog類中可以訪問伴生對象Dog的私有屬性 println(Dog.CONSTANT + name )

}

} /*

** 伴生對象 / object Dog { //伴生對象中的私有屬性* private val CONSTANT = "****汪汪汪 : " def main(args: Array[String]) { val p = new Dog //訪問私有的字段name p.name = "123" p.printName()

}

}</pre>

|

5.2.3. apply方法

通常我們會在類的伴生對象中定義apply方法兼雄,當(dāng)遇到類名(參數(shù)1,...參數(shù)n)時apply方法會被調(diào)用

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala</pre>

<pre style="mso-pagination:widow-orphan;background:white"> /*

  • Created by ZX on 2015/11/14.

/ object ApplyDemo { def main(args: Array[String]) { //調(diào)用了Array伴生對象的apply方法 //def apply(x: Int, xs: Int): Array[Int]

//arr1中只有一個元素5* val arr1 = Array(5)

println(arr1.toBuffer) //new了一個長度為5的array吟逝,數(shù)組里面包含5個null var arr2 = new Array(5)

}

}</pre>

|

5.2.4. 應(yīng)用程序?qū)ο?/h3>

Scala程序都必須從一個對象的main方法開始,可以通過擴(kuò)展App特質(zhì)赦肋,不寫main方法澎办。

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/14.

/ object AppObjectDemo extends App{ //不用寫main方法 println("I love you Scala")

}</pre>

|

5.3. 繼承

5.3.1. 擴(kuò)展類

在Scala中擴(kuò)展類的方式和Java一樣都是使用extends關(guān)鍵字

5.3.2. 重寫方法

在Scala中重寫一個非抽象的方法必須使用override修飾符

5.3.3. 類型檢查和轉(zhuǎn)換

|

Scala

|

Java

|
|

obj.isInstanceOf[C]

|

obj instanceof C

|
|

obj.asInstanceOf[C]

|

(C)obj

|
|

classOf[C]

|

C.class

|

5.3.4. 超類的構(gòu)造

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.scala /*

  • Created by ZX on 2015/11/10.

/ object ClazzDemo { def main(args: Array[String]) { *//val h = new Human

//println(h.fight)* }

} trait Flyable{ def fly(): Unit ={

println("I can fly")

} def fight(): String } abstract class Animal { def run(): Int val name: String } class Human extends Animal with Flyable{ val name = "abc" //打印幾次"ABC"? val t1,t2,(a, b, c) = {

println("ABC")

(1,2,3)

}

println(a)

println(t1._1) //在Scala中重寫一個非抽象方法必須用override修飾 override def fight(): String = { "fight with 棒子" } //在子類中重寫超類的抽象方法時嘲碱,不需要使用override關(guān)鍵字,寫了也可以 def run(): Int = { 1 }

}</pre>

|

6. 模式匹配和樣例類

Scala有一個十分強(qiáng)大的模式匹配機(jī)制局蚀,可以應(yīng)用到很多場合:如switch語句麦锯、類型檢查等。

并且Scala還提供了樣例類琅绅,對模式匹配進(jìn)行了優(yōu)化扶欣,可以快速進(jìn)行匹配

6.1. 匹配字符串

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases import scala.util.Random object CaseDemo01 extends App{ val arr = Array("YoshizawaAkiho", "YuiHatano", "AoiSola") val name = arr(Random.nextInt(arr.length)) name match { case "YoshizawaAkiho" => println("****吉澤老師...") case "YuiHatano" => println("****波多老師...") case _ => println("****真不知道你們在說什么...")

}

}</pre>

|

6.2. 匹配類型

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases import scala.util.Random object CaseDemo01 extends App{ //val v = if(x >= 5) 1 else if(x < 2) 2.0 else "hello" val arr = Array("hello", 1, 2.0, CaseDemo) val v = arr(Random.nextInt(4))

println(v) v match { case x: Int => println("Int " + x) case y: Double if(y >= 0) => println("Double "+ y) case z: String => println("String " + z) case _ => throw new Exception("not match exception")

}

}</pre>

|

注意****:case y: Double if(y >= 0) => ...

模式匹配的時候還可以添加守衛(wèi)條件。如不符合守衛(wèi)條件千扶,將掉入case _中

6.3. 匹配數(shù)組料祠、元組

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases object CaseDemo03 extends App{ val arr = Array(1, 3, 5) arr match { case Array(1, x, y) => println(x + " " + y) case Array(0) => println("only 0") case Array(0, _) => println("0 ...") case _ => println("something else"*)

} val lst = List(3, -1) lst match { case 0 :: Nil => println("only 0") case x :: y :: Nil => println(s"x: $x y: $y") case 0 :: tail => println("0 ...") case _ => println("something else")

} val tup = (2, 3, 7) tup match { case (1, x, y) => println(s"1, $x , $y") case (_, z, 5) => println(z) case _ => println("else")

}

}</pre>

|

注意:在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。

9 :: List(5, 2) :: 操作符是將給定的頭和尾創(chuàng)建一個新的列表

注意::: 操作符是右結(jié)合的澎羞,如9 :: 5 :: 2 :: Nil相當(dāng)于 9 :: (5 :: (2 :: Nil))

6.4. 樣例類

在Scala中樣例類是一中特殊的類髓绽,可用于模式匹配。case class是多例的妆绞,后面要跟構(gòu)造參數(shù)顺呕,case object是單例的

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases import scala.util.Random</pre>

<pre style="mso-pagination:widow-orphan;background:white">case class SubmitTask(id: String, name: String) case class HeartBeat(time: Long) case object CheckTimeOutTask object CaseDemo04 extends App{ val arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001")) arr(Random.nextInt(arr.length)) match { case SubmitTask(id, name) => { println(s"$id, $name")//前面需要加上s, $id直接取id的值 } case HeartBeat(time) => {

println(time)

} case CheckTimeOutTask => {

println("check")

}

}

}</pre>

|

6.5. Option類型

在Scala中Option類型樣例類用來表示可能存在或也可能不存在的值(Option的子類有Some和None)。Some包裝了某個值括饶,None表示沒有值

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases object OptionDemo { def main(args: Array[String]) { val map = Map("a" -> 1, "b" -> 2) val v = map.get("b") match { case Some(i) => i case None => 0 }

println(v) //更好的方式 val v1 = map.getOrElse("c", 0)

println(v1)

}

}</pre>

|

6.6. 偏函數(shù)

被包在花括號內(nèi)沒有match的一組case語句是一個偏函數(shù)株茶,它是PartialFunction[A, B]的一個實(shí)例,A代表參數(shù)類型图焰,B代表返回類型启盛,常用作輸入模式匹配

|

<pre style="mso-pagination:widow-orphan;background:white">package cn.itcast.cases object PartialFuncDemo { def func1: PartialFunction[String, Int] = { case "one" => 1 case "two" => 2 case _ => -1 }</pre>

<pre style="mso-pagination:widow-orphan;background:white"> def func2(num: String) : Int = num match { case "one" => 1 case "two" => 2 case _ => -1 }</pre>

<pre style="mso-pagination:widow-orphan;background:white"> def main(args: Array[String]) {

println(func1("one"))

println(func2("one"))

} }</pre>

|

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市技羔,隨后出現(xiàn)的幾起案子僵闯,更是在濱河造成了極大的恐慌,老刑警劉巖藤滥,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棍厂,死亡現(xiàn)場離奇詭異,居然都是意外死亡超陆,警方通過查閱死者的電腦和手機(jī)牺弹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來时呀,“玉大人张漂,你說我怎么就攤上這事〗髂龋” “怎么了航攒?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趴梢。 經(jīng)常有香客問我漠畜,道長币他,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任憔狞,我火速辦了婚禮蝴悉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瘾敢。我一直安慰自己拍冠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布簇抵。 她就那樣靜靜地躺著庆杜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碟摆。 梳的紋絲不亂的頭發(fā)上晃财,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音典蜕,去河邊找鬼断盛。 笑死,一個胖子當(dāng)著我的面吹牛嘉裤,可吹牛的內(nèi)容都是我干的郑临。 我是一名探鬼主播栖博,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼屑宠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仇让?” 一聲冷哼從身側(cè)響起典奉,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丧叽,沒想到半個月后卫玖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡踊淳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年假瞬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迂尝。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡脱茉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垄开,到底是詐尸還是另有隱情琴许,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布溉躲,位于F島的核電站榜田,受9級特大地震影響益兄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箭券,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一净捅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邦鲫,春花似錦灸叼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滔以,卻和暖如春捉腥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背你画。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工抵碟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坏匪。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓拟逮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親适滓。 傳聞我的和親對象是個殘疾皇子敦迄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Scala與Java的關(guān)系 Scala與Java的關(guān)系是非常緊密的!凭迹! 因?yàn)镾cala是基于Java虛擬機(jī)罚屋,也就是...
    燈火gg閱讀 3,424評論 1 24
  • 數(shù)組是一種可變的、可索引的數(shù)據(jù)集合嗅绸。在Scala中用Array[T]的形式來表示Java中的數(shù)組形式 T[]脾猛。 v...
    時待吾閱讀 948評論 0 0
  • scala不刻意區(qū)分原生類型和引用類型 scala單參數(shù)方法可以用運(yùn)算符形式調(diào)用,例如: scala沒有提供"++...
    AlienPaul閱讀 359評論 0 3
  • Scala的集合類可以從三個維度進(jìn)行切分: 可變與不可變集合(Immutable and mutable coll...
    時待吾閱讀 5,807評論 0 4
  • 無意間聽到一首歌愉昆,叫《八零后的歌》。歌詞里有這么幾句:我是八零后啊造锅,生活有點(diǎn)忙撼唾,房子車子票子,老婆孩子妹子,所有壓...
    LPaper生活文件閱讀 772評論 0 6