當前位置:成語大全網 - 成語詞典 - 如何實現Scala的above,beside和toString

如何實現Scala的above,beside和toString

Spark也是基於JVM,我們構築分布式系統,借助JVM,而不壹定是Java語言。 Spark和消息中間件KAFKA等都是用Scala編寫的,學好Scala是掌握Spark的關鍵。

Scala基礎語法入門實戰

首先,參照相關攻略,在Linux下分別下載安裝Java、Scala,然後配置Java和Scala環境變量。安裝完畢,在終端敲入scala即可進入Scala命令行,如下所示:

root@Master:~# scala

Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66).

Type in expressions to have them evaluated.

Type :help for more information.

簡單測試

scala> 1+2

res0: Int = 3

scala> 1.5*2

res1: Double = 3.0

scala> 3*res1

res2: Double = 9.0

//按Tab鍵,命令自動補全

scala> res2.to

toByte toChar toDouble toFloat toInt toLong toShort toString

變量

var聲明可變變量;val聲明不可變變量。

val聲明的不可變變量,不希望數據被改變,RDD內部的數據都是不可變,所以在Spark中壹般都是使用val。

//下面聲明了壹個不可變變量result,result的值不可改變。

scala> val result=2+10

result: Int = 12

//假若修改result的值,會提示出錯,如下:

scala> result=13

<console>:8: error: reassignment to val

result=13

//var聲明可變變量:

scala> var name="Spark"

name: String = Spark

scala> name="Scala" //可以修改變量name的值

name: String = Scala

scala> name //name的值現在為Scala

res4: String = Scala

//val聲明不可變變量

//age被聲明為Int類型的不可變變量

scala> val age: Int=0

age: Int = 0

//聲明為String類型

scala> val name:String=null

name: String = null

壹行代碼聲明多個變量

scala> val age1,age2,age3=0

age1: Int = 0

age2: Int = 0

age3: Int = 0

基本數據類型的自動轉換操作

Scala自己可以完成基本數據類型的自動轉換操作。

//輸入整數10,按Tab鍵盤,可以看見它本身的很多方法:

scala> 10.to

toByte toChar toDouble toFloat toInt toLong toShort toString

scala> 10.toString

res5: String = 10

scala> 0.to(5)

res6: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5)

給了我們壹個不可變的集合,獲得的結果是:0~5,所以Scala壹切皆對象!

Scala隱私轉換:

當類型本身沒有沒有這個方法,但是又需要調用這個方法時,內部就會自動觸發隱式轉換。剛才的示例中,Int本身沒有to這樣的方法,Scala引擎內部會隱式自動轉換成RichInt,就像上面0.to(5)這樣的調用,RichInt對象類型才有to這樣的函數。

scala> 1+1

res7: Int = 2

//因為Scala壹切皆對象,所以以上示例又可以寫成:

scala> 1.+(1)

res9: Double = 2.0

這個示例,內部其實就是Int的壹個隱式轉換,+是類的壹個方法。

Scala沒有++、---操作運算:

scala> var age=10

age: Int = 10

// Scala沒有++、---操作運算

scala> age++

<console>:9: error: value ++ is not a member of Int

age++

^

//但是++運算可以用下面方式實現:

scala> age +=1

scala> age

res12: Int = 11

求最大、最小值

scala> min(20,4)

<console>:8: error: not found: value min

min(20,4)

^

該示例因為沒有導入庫,所以出錯。

scala> import scala.math._ //導入math庫

import scala.math._

scala> min(20,4)

res14: Int = 4

apply工廠構造實現方法

在Spark中,大量的實例的構造都是使用了apply方式。

scala> Array(1,2,3,4)

res15: Array[Int] = Array(1, 2, 3, 4)

scala> val array=Array(1,2,3,4)

array: Array[Int] = Array(1, 2, 3, 4)

//array是壹個聲明整數類型的數組變量, 其實內部是自動調用了Array.apply方法,等同如下:

scala> val array = Array.apply(1,2,3,4)

array: Array[Int] = Array(1, 2, 3, 4)

條件控制、循環

// if表達式示例:

scala> if(age>=18) "成年人" else "小孩"

res16: String = 成年人

scala> val result=if(age>=18) "成年人" else "小孩"

result: String = 成年人

scala> result

res17: String = 成年人

scala> val result = if(age>=18){

| "adult"

| buffered=10

| buffered

| }

以上壹個代碼塊,代碼塊後面有個返回值buffered,代碼塊的返回值就是最後壹行的值。

打印值

scala> println("Spark") //輸出壹行字符串並換行

Spark

scala> println("\nSpark") //換行,輸出壹行字符串再換行。\n是換行轉義符。

Spark

scala> print("Spark") //輸出壹行字符串,不換行

Spark

scala>

填充占位符

scala> printf("%s是大數據框架的未來", "Spark") //%s是占位符

Spark是大數據框架的未來

讀取內容

readLine用於讀取輸入的內容

scala> readLine //此時敲入Scala之後,然後回車

res28: String = Scala

scala> res28

res29: String = Scala

補充說明,readLine是壹個方法,如果方法如果沒有參數,那麽可以不帶括號,readLine()跟readLine效果壹樣。

循環

//聲明壹個可變變量,初始值為100

scala> var element=100

element: Int = 100

//while循環示例:

scala> while(element>90){

| println(element)

| element -= 1

| }

100

99

98

97

96

95

94

93

92

91

scala> 0 to element

res32: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90)

//for循環遍歷並打印

scala> for(i<-80 to element) println(i)

80

81

82

83

84

85

86

87

88

89

90

//循環並增加條件判斷

scala> for(i<-0 to element if i%2==0) print(i+" ")

0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90

//for循環,並break退出

scala> import scala.util.control.Breaks._ //添加break引用

import scala.util.control.Breaks._

scala> for(i<-1 to 10){

| if(i==4) break

| println(i)

| }

1

2

3

scala.util.control.BreakControl

//循環,並return

scala> val n=5

n: Int = 5

scala> def f1:Any = {

| for(i <-1 to 10){

| if(i==n) return i

| println(i)

| }

| }

f1: Any

scala> f1

1

2

3

4

res1: Any = 5

解釋以上代碼塊,def是定義壹個函數。f1就是壹個函數。

二、 Scala函數入門實戰

函數示例

函數的定義使用def關鍵字,並且函數體最後有返回值。

//聲明了壹個函數f3,兩個參數:param1是String類型,param2為Int類型。param2默認值為30,因為有了默認值,那麽在調用上可以不傳param2。

scala> def f3(param1:String, param2:Int=30) = param1 + param2

f3: (param1: String, param2: Int)String

//調用函數f3,傳入第壹個參數param1值為Spark,沒有傳入第二個參數,默認為30。

scala> f3("Spark")

res4: String = Spark30

//帶名參數調用,即在函數調用時,顯示指定參數名,並不按順序傳入。

scala> f3(param2=100, param1="Scala")

res5: String = Scala100

//變長參數, 定義了壹個sum函數,參數numbers是變成參數,即傳入的Int變量個數不定。在函數體中,對傳入的全部Int變量進行循環遍歷並累計求和,最後把結果返回。

scala> def sum(numbers: Int*)={var result=0; for(element<-numbers) result +=element; result}

sum: (numbers: Int*)Int

scala> sum(1,2,3,4,5,6,7,8,9,10)

res1: Int = 55

//下面示例是壹個非常經典的語法

scala> sum(1 to 10: _*) // _* 表示提取裏面的每個元素, 然後作為變長參數傳遞

res3: Int = 55

過程

沒有返回值的函數就是過程。

//這是壹個函數

scala> def morning(content:String) = "Good" + content

morning: (content: String)String

//這是壹個過程

scala> def morning(content:String) { println( "Good" + content)}

morning: (content: String)Unit

//強制聲明壹個過程

scala> def morning(content:String):Unit = "Good" + content

morning: (content: String)Unit

聲明lazy類型

scala> import scala.io.Source._ //導入引用庫

import scala.io.Source._

//聲明壹個lazy類型的變量content,打開壹個不存在的文件。

scala> lazy val content = fromFile("/root/txt")

content: scala.io.BufferedSource = <lazy>

以上示例執行不會出錯,表明content變量並沒有執行。

//如果去掉lazy關鍵字,那麽會出錯,提示文件不存在。

scala> val content = fromFile("/root/txt")

java.io.FileNotFoundException: /root/txt (No such file or directory)

at java.io.FileInputStream.open0(Native Method)

at java.io.FileInputStream.open(FileInputStream.java:195)

at java.io.FileInputStream.<init>(FileInputStream.java:138)

耗時的操作,在大型分布式系統中,比較常見。聲明lazy類型的變量,在需要的時候才去執行。

異常

//首先導入相關引用包

scala> import java.io._

import java.io._

scala>

//示例打開壹個存在的文件,使用try…catch捕獲異常

scala> try{

| val content = fromFile("/root/.bashrc").mkString

| }catch{

| //case是壹個偏函數

| case _: FileNotFoundException => println("Oh, file not found!")

| }finally{

| println("Ok!")

| }

Ok!

scala>

//示例打開壹個不存在的文件,使用try…catch捕獲異常

scala> try{

| val content = fromFile("/root/.bashrc111").mkString

| }catch{

| //case是壹個偏函數

| case _: FileNotFoundException => println("Oh, file not found!")

| }finally{

| println("Ok!")

| }

Oh, file not found!

Ok!

三、 Scala中Array、Map、Tuple實戰

Array

//聲明變量arr為Array整數類型的數組,包含5個元素。

scala> val arr= new Array[Int](5)

arr: Array[Int] = Array(0, 0, 0, 0, 0)

//訪問第三個元素

scala> arr(2)

res15: Int = 0

//修改第三個元素

scala> arr(2)=8

//再次查看arr數組,發現第三個元素值已經變成8了。

scala> arr

res17: Array[Int] = Array(0, 0, 8, 0, 0)

補充說明,剛才聲明arr數組變量時,所以把它聲明為val不可變變量,這只是表明arr的地址不可以變,但是數組裏面的元素還是可以變化的。

//在Spark中,更常見地創建數組是直接通過類名

scala> val arr1 = Array("Scala", "Spark")

arr1: Array[String] = Array(Scala, Spark)

該示例中,聲明arr1為數組變量時,沒有使用new關鍵字,也沒有指定String類型,系統默認根據元素值,自動推導出元素的類型為String。

沒有使用new關鍵字,其實它內部調用了apply方法, apply是工廠類構造器。等同於下面的寫法:

scala> val arr1 = Array.apply("Scala", "Spark")

arr1: Array[String] = Array(Scala, Spark)

//給Array增加元素。下面寫法會出錯,給arr1數組增加壹個元素,比如:

scala> arr1(2)="Hadoop"

java.lang.ArrayIndexOutOfBoundsException: 2

at .<init>(<console>:16)

at .<clinit>(<console>)

……

如果需要給Array增加元素,那麽此時就應該使用ArrayBuffer類型。

ArrayBuffer

//首先導入庫

scala> import scala.collection.mutable.ArrayBuffer

import scala.collection.mutable.ArrayBuffer

//定義壹個ArrayBuffer類型的變量arrbuffer

scala> val arrbuffer=ArrayBuffer[Int]()

arrbuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

//向arrbuffer中增加壹個元素,值為10

scala> arrbuffer += 10

res23: arrbuffer.type = ArrayBuffer(10)

//向arrbuffer中增加多個元素

scala> arrbuffer += (11,1,3,5)

res25: arrbuffer.type = ArrayBuffer(10, 11, 1, 3, 5)

//查看arrbuffer的內容

scala> arrbuffer

res26: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 1, 3, 5)

//向arrbuffer中增加壹個數組

scala> arrbuffer ++= Array(1,2,3,4)

res27: arrbuffer.type = ArrayBuffer(10, 11, 1, 3, 5, 1, 2, 3, 4)

//截掉arrbuffer後面的3個元素

scala> arrbuffer.trimEnd(3)

//再次查看arrbuffer的內容,發現元素:2, 3, 4被截掉

scala> arrbuffer

res29: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 1, 3, 5, 1)

//在第5個位置,插入元素值100

scala> arrbuffer.insert(5,100)

//查看arrbuffer的內容

scala> arrbuffer

res32: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 1, 3, 5, 100, 1)

//在第2個位置,插入多個元素:200,300,400

scala> arrbuffer.insert(2,200,300,400)

//查看arrbuffer的內容

scala> arrbuffer

res34: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 200, 300, 400, 1, 3, 5, 100, 1)

//從arrbuffer中移除第3個位置上的元素

scala> arrbuffer.remove(3)

res35: Int = 300 //被移除的值是300

//再次查看arrbuffer的內容,發現第3個位置上的元素300不見了。

scala> arrbuffer

res36: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 200, 400, 1, 3, 5, 100, 1)

//從arrbuffer中移除第2個位置開始的,3個元素,即:200, 400, 1

scala> arrbuffer.remove(2,3)

//再次查看arrbuffer的內容,發現三個元素:200, 400, 1 不見了。

scala> arrbuffer

res38: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 11, 3, 5, 100, 1)

//可變數組變成不可變數組,此時arr2是壹個不可變數組

scala> val arr2 = arrbuffer.toArray

arr2: Array[Int] = Array(10, 11, 3, 5, 100, 1)

// Array.toBuffer的結果變成壹個ArrayBuffer

scala> arr2.toBuffer

res40: scala.collection.mutable.Buffer[Int] = ArrayBuffer(10, 11, 3, 5, 100, 1)

//遍歷壹個數組:

scala> for(elem <- arr2) println(elem)

10

11

3

5

100

1

//遍歷數組時加上條件

scala> arr2

res42: Array[Int] = Array(10, 11, 3, 5, 100, 1)

//遍歷時的條件,跳過偶數位上的元素

scala> for(i <- 0 until (arr2.length, 2)) println(arr2(i))

10

3

100

此時打印出來的結果,跳過了元素:11、5、1

//從尾部開始遍歷

scala> for(i <- (0 until arr2.length).reverse) println(arr2(i))

1

100

5

3

11

10

//對數組進行排序

//導入排序包

scala> import scala.util.Sorting

import scala.util.Sortin