大資料之scala(一) --- 安裝scala,簡單語法介紹,條件表示式,輸入和輸出,迴圈,函式,過程,lazy ,異常,陣列
阿新 • • 發佈:2018-11-09
一、安裝和執行Scala解釋程式 --------------------------------------------- 1.下載scala-2.11.7.msi 2.管理員執行--安裝 3.進入scala/bin,找到scala.bat,管理員執行,進入scala命令列 二、REPL ----------------------------------------------------- Read + Evaluate + Print + Loop 三、Scala的簡單語法介紹 ---------------------------------------------- 1.可以直接執行表示式 //列印一個數組 scala> 1 to 10 res1: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 2.變數和常量 val : value常量,賦值之後是不能改變的 var : 變數,可以隨意賦值和更改 scala> val a = 100; scala> var b = 100; scala> b = 200; 3.scala也是有型別的,但是可以不寫,使用var代替 scala> var a = "hello world"; scala> var a:String = "hello world"; a: String = hello 4.常用資料型別 a.Byte Char Short Int Long Float Double b.跟java不同,這些基本資料型別都是類 c.可以對數字執行方法 scala> 1.toString(); res2: String = 1 scala> 1.to(10); res3: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 5.操作符 + - * / % 的過載 a. a 方法 b == a.方法(b); scala> 1.+(2) res5: Int = 3 scala> 1 + 2 res6: Int = 3 scala> 1.to(10) res7: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> 1 to 10 res8: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) b.scala中並沒有 ++ -- ,請使用 +=1 -=1 6.呼叫函式和方法 a.scala函式是沒有物件的,但是方法是有物件的,方法是通過物件進行呼叫的 最值函式: min(1,2),不需要依賴任何物件,直接可使用 操作符過載方法: 1.+(2) 1 + 2 這是方法,需要物件呼叫 b.scala中沒有靜態方法,但是scala有單例物件 c.不帶引數的scala方法,通常不使用圓括號 scala> 1.toString() //帶括號 scala> 1.toString //不帶括號 scala> 1 toString //運算子的方式 7.導包 scala> import scala.math._ //_ ===> * 8.apply方法 scala> "hello".apply(1) //apply:,應用。取出第幾個元素 res1: Char = e scala> "hello"(1) //apply的簡寫方式 res2: Char = e 9.Any是所有型別的超類,相當於java中的object 10.型別轉換 scala> 1.toString res3: String = 1 scala> "1000".toInt res4: Int = 1000 11.空值Unit -- scala的表示式都有值,賦值表示式返回的是空值Unit,表現為(),類似於java中的void scala> val a = (s=3) a: Unit = () scala> val y = () y: Unit = () scala> val y:Unit = () y: Unit = () 12.:help檢視幫助 四、條件表示式 ------------------------------------------------------------- 1.if -- else scala> val s = if(x > 0) 1 else -1 等價於 scala> if(x > 0) s = 1 else s = -1 2.塊語句宣告符{} : 表示本行語句尚未結束,相當於換行 a.如果想換行,那麼換行之前的語句就表示結束了。那麼else if 就不知道是啥了。這種情況就需要使用大括號,告知大括號所在行尚未結束 //表示兩個表示式 scala> if(x > 0) 1 scala> else if (x == 0) 0 else -1 //表示一個表示式 scala> if(x > 0) { 1 } else if (x == 0) 0 else -1 3.paste模式 :paste // 進入貼上模式,這個時候無論怎麼換行, 都不會結束語句 ctrl + D //退出貼上模式,開始計算貼上模式中的內容 scala> :paste // Entering paste mode (ctrl-D to finish) if (2 > 1) 1 else 2 // Exiting paste mode, now interpreting. res10: Int = 1 五、輸入和輸出函式 ----------------------------------------------------------- a.print / println scala> print ("answer: ") answer: scala> print ("answer: " + 42 ) answer: 42 scala> println(42) 42 b.printf(佔位符 %s %d %f) scala> printf("hello,%s! You are %d years old.\n", "tom" , 43) hello,tom! You are 43 years old. c.readLine[readInt readDouble readByte readShort ReadBoolean...] scala> val name = readLine("your name :") your name :name: String = tom scala> val age = readInt() age: Int = 15 scala> printf("hello,%s! You are %d years old.\n", name , age) hello,tom! You are 15 years old. 六、迴圈 ------------------------------------------------------------ 1.while迴圈 scala> var n = 5; n: Int = 5 scala> while(n > 0){ | print("hello"); | n -= 1; | } hellohellohellohellohello 2.while迴圈列印99乘法表 scala> var i = 1; i: Int = 1 scala> :paste // Entering paste mode (ctrl-D to finish) while(i <= 9){ var j = 1; while( j <= i) { printf("%d x %d = %d\t",j,i,(j*i)); print(" "); j += 1; } println(); i += 1; } // Exiting paste mode, now interpreting. 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 3.外部命令載入檔案,執行99乘法表 a.新建檔案 D:\share\scala\workspace\99.scala b.貼上內容 var i = 1; while(i <= 9){ var j = 1; while( j <= i) { printf("%d x %d = %d\t",j,i,(j*i)); print(" "); j += 1; } println(); i += 1; } c.使用load命令載入 scala> :load D:\share\scala\workspace\99.scala Loading D:\share\scala\workspace\99.scala... i: Int = 1 1 x 1 = 1 1 x 2 = 2 2 x 2 = 4 1 x 3 = 3 2 x 3 = 6 3 x 3 = 9 1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16 1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25 1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36 1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49 1 x 8 = 8 2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64 1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81 4.百錢買百雞 公雞:5塊/只 母雞:3塊/只 小雞:1塊/3只 var gong = 0; while(gong <= 20 ) { var mu = 0; while(mu <= 33) { var xiao = 0; while(xiao < 100) { if( gong * 5 + mu * 3 + xiao/3 == 100 && gong + mu + xiao == 100) { printf(gong,mu,xiao); } xiao += 3; } mu += 1; } gong += 1; } Loading D:\share\scala\workspace\100.scala... gong: Int = 0 0_25_75 4_18_78 8_11_81 12_4_84 5.for迴圈 a. to: 閉區間,將 1 到 10 輪流賦值給x scala> for(x <- 1 to 10){ | print(x + "\t"); | } 1 2 3 4 5 6 7 8 9 10 b. until :左閉右開區間,將1 到 9 輪流賦值給x scala> for (x <- 1 until 10) | { | print(x + "\t"); | } 1 2 3 4 5 6 7 8 9 6.scale沒有break,也沒有continue a.可以使用boolean變數進行控制 b.使用巢狀函式 -- 可以從函式中return c.使用Breaks物件的break方法 import scala.util.control.Breaks._ breakable{ for(...){ if(...) break; //退出breakable塊 } } breakable{ for(x <- 1 to 10) { print(x); break; } } 7.高階for迴圈 a.多個 <- ,用分號分割 scala> for( i <- 1 to 3; j <- 1 to 3) print (( i + ":" + j) + "\t") //-- 1:1 1:2 1:3 2:1 2:2 2:3 3:1 3:2 3:3 b.多個 <- ,用分號分割,每個 <- 新增獨立的判斷 scala> for( i <- 1 to 3 if i != 2; j <- 1 to 3) print (( i + ":" + j) + "\t") //-- 1:1 1:2 1:3 3:1 3:2 3:3 scala> for( i <- 1 to 3 if i != 2; j <- 1 to 3 if j != i) print (( i + ":" + j) + "\t") //-- 1:2 1:3 3:1 3:2 c.<- 過程中,可以定義任意多個變數,使用分號分割 scala> for( i <- 1 to 3 if i != 2; kk=i-1 ; j <- kk to 3 if j != i) print (( i + ":" + j) + "\t") //-- 1:0 1:2 1:3 3:2 d.yield,是迴圈中處理每個元素,產生新集合 scala> for (x <- 1 to 10 ) yield x % 2 ; res12: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 0, 1, 0, 1, 0, 1, 0, 1, 0) 七、函式 ---------------------------------------------------------------------- 1.定義函式 def fac(n : Int) = { var r = 1 for(i <- 1 to n) r = r * i r } def add(a:Int,b:Int) : Int = { var c = a + b; return c; } def add(a:Int,b:Int) = { var c = a + b; c; } 2.引數和返回值 scala的函式,你必須給出所有的引數以及型別,但是不必須指定返回值和返回型別 預設執行語句的之後一個表示式的值就是返回值 3.scala實現遞迴 4! = 4 * 3 ![遞迴函式必須顯示定義返回值型別] def func(n : Int):Int = { if(n != 1) return n * func(n-1); else return 1; } 4.引數的預設值和帶名引數 def func2(head:String = "[", str:String = "tom" , tail:String = "]") = { head + str + tail; } scala> func2() res23: String = [tom] scala> func2("11","22"); res21: String = 1122] scala> func2(str = "222"); res22: String = [222] 5.變長引數(Int*) 和 序列引數( :_* ) [sum]:求和 def sum(args : Int*) = { var sum = 0; for( arg <- args ) sum += arg; sum; } scala> sum(10) res24: Int = 10 scala> sum(10,9,8,7,6) res25: Int = 40 scala> sum(1 to 10:_*) //注意,不能直接使用1 to 10,是錯誤的,要加上 :_* res26: Int = 55 [reSum]:遞迴求和 def reSum(args : Int*) : Int = { if(args.length == 0) return 0; else return args.head + reSum(args.tail:_*); } scala> reSum(1 to 10 :_*) res29: Int = 55 八、過程 ------------------------------------------------------------------------- 1.過程 -- 無返回值的函式的一種特殊表示方法 函式體包含在花括號當中,但是沒有前面的 = 號。返回型別是Unit 2.過程不返回值,呼叫它僅僅是為了輔助作用,比如輔助列印一些符號和格式 3.語句 def out(a : Int) { println("***" + a + "***"); } scala> out(22) ***22*** 九、懶值lazy -- 延遲計算 ------------------------------------------------------------------------- 1.當val被宣告為lazy的時候,它的初始化將被推遲,直到我們首次呼叫 //直到訪問words常量,才去開啟檔案,讀取檔案內容成字串 scala> lazy val words = scala.io.Source.fromFile("d:\\calllog.log").mkString words: String = <lazy> scala> print(words); 15811111111,15032295555,2018/06/01 04:44:33,201 18022222222,15732641111,2018/02/07 18:01:36,297 17731086666,18301581111,2018/02/13 03:17:41,133 18332561111,13341101111,2018/06/12 11:07:55,304 13341101111,18301581111,2018/03/26 05:06:58,210 18641241111,15733218888,2018/03/02 07:21:17,235 13341101111,15614209999,2018/10/12 11:12:12,303 15778421111,15614209999,2018/01/05 02:44:58,134 18620191111,18332561111,2018/02/27 20:45:59,499 18301581111,13269364444,2018/06/01 15:13:22,345 15614209999,17731086666,2018/07/08 23:45:45,236 18332561111,13269364444,2018/04/17 19:08:46,583 15338597777,15732641111,2018/08/21 13:37:39,506 15032295555,13269364444,2018/01/05 10:11:19,294 15032295555,13560191111,2018/08/04 16:51:30,260 13341101111,18301581111,2018/09/09 02:15:13,265 13269364444,15733218888,2018/08/21 09:10:57,067 十、異常 ------------------------------------------------------------- 1. => 交給 try{ "hello".toInt; } catch{ //交給 case _:Exception => print("xxxx") ; case ex:java.io.IOException => print(ex) } 2. _ a.引入包的時候,表示統配,相當於* b.1 to 10 :_* ,轉成序列 c.case _:Exception => print("xxxx") ; 十一、陣列 ----------------------------------------------------------------- 1.定長陣列 //10個整數的陣列,預設所有元素的初始值是0 val nums = new Array[Int](10); //已提供初始值,不需要new ,不需要型別,靠推斷 val s = Array("Hello","world") 2.訪問陣列的元素 //新建陣列 scala> val s = Array("Hello","world") //取值 scala> print(s(0)) //-- Hello //賦值 scala> s(0) = "tom" scala> print(s(0)) //-- tom 3.變長陣列 -- 陣列緩衝 -- ArrayBuffer[java::ArrayList] //導包 import scala.collection.mutable.ArrayBuffer //新建可變陣列 val b = ArrayBuffer[Int]() //尾端新增一個元素 b += 1 //尾端新增多個元素 b += (1,2,3,4) //尾端新增新的可變集合 b ++= Array(6,7,8) //移除尾端5個元素 b.trimEnd(5) //移除開始的2個元素 b.trimStart(2) //插入一個[效率不高] b.insert(2,6) //插入多個[效率不高] -- 第二的位置插入6 7 8 b.insert(2,6,7,8) //移除指定位置的元素 b.remove(2) //移除指定位置的多個元素 -- 從第二個位置開始移除,移除3個元素 b.remove(2,3) 4.遍歷陣列 a.普通for for( i <- 0 until b.length) println(i + ":" + b(i)) b.foreach for( i <- b) println(i) 5.陣列轉換 a.不修改原來陣列,產生新的陣列 val a = Array(2,3,4,5) val res = for(e <- a) yield 2 * a //含有yield的表示式,每次迭代對應一個 b.過濾 val a = Array(1 to 10:_*) //產生陣列 a.filter(_ % 2 == 0).map(_ * 2) //filter過濾器; _ 通配; map對映,相當於yield 6.陣列常用方法 scala> arr.sum scala> arr.min scala> arr.max 7.排序 scala> import scala.util.Sorting._ scala> val arr = Array(1,4,3,2) scala> quickSort(arr) //arr有序 val b = ArrayBuffer(1,7,2,9) val bSorted = b.sorted(_ < _) //b沒有被改變;bSorted是ArrayBuffer val bSorted = b.sorted(_ > _) //b沒有被改變;bSorted是ArrayBuffer 8.陣列toString scala> arr.mkString("<<",",",">>") //<<1,2,3,4>> 9.多維陣列 a.新建二維陣列 var arr = new Array[Array[Int]](4) var arr = Array.ofDim[Int](3,4) //Int 型別 3行 4列 b.賦值 arr(0) = Array(1) arr(1) = Array(1,2) arr(2) = Array(1,2,3) arr(3) = Array(1,2,3,4) arr(row)(column) = 42 //給row行column列賦值 c.遍歷二維陣列 for(x <- arr){ for(y <- x){ print(y) } println() }