1. 程式人生 > >大資料之scala(一) --- 安裝scala,簡單語法介紹,條件表示式,輸入和輸出,迴圈,函式,過程,lazy ,異常,陣列

大資料之scala(一) --- 安裝scala,簡單語法介紹,條件表示式,輸入和輸出,迴圈,函式,過程,lazy ,異常,陣列

一、安裝和執行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()
            }