Spark學習(二)scala語法


一,變量

1,基本數據類型

2,基本運算符

3,定義變量

4,復雜變量

 (1)定義數組Array:

  •    聲明:val aList=new Array[數據類型type](n):聲明存儲數據類型為type的n個對象,數組初始化為null
  •    聲明:val aList=Array(n1,n2,n3...):聲明時,可以不用聲明數據類型。
  •    調用:aList(m):調用第m個元素。
  •    聲明多維數組:val aList=Array.ofDim[數據類型](a,b):聲明行為a,列為b的二維數組
  •    調用多維數組中的元素:aList(a1)(b1):調用數組中行為a1,列為b1的元素

(2)定義元組Tuple(對多個不同類型的對象的簡單封裝):

  •      聲明: val tStudent=("name1",23,"男",560.00):聲明元組類型學生的信息為(姓名,年齡,性別,月開銷)
  •      調用:tStudent._1(取出"name1");tStudent._2(取出23);tStudent._3(取出"男")....

(3)定義容器Collection(導包scala.collection;scala.collection.mutable;scala.collection.immutable)

       scala.collection:封裝了可變容器和不可變容器的通用操作的超類(從上到下依次繼承都是特質(類似Java的接口),不是具體的容器

        

         foreach方法:遍歷當前容器內所有元素

(4)定義序列Sequence(如上圖Seq有兩個子序列:IndexedSeq和LinearSeq)有存入數據有先后順序,可以重復

       LindearSeq:列表和隊列可以繼承該類

                        List(列表):具體的容器類,列表內的對象必須是同類型,列表內的值不可變(必須導包scala.collection.immutable)

                                          定義:val slPeople=List("張三","李四","王五"......)

                                          頭部:head;尾部:tail    獲取頭部(第一個元素:slPeople.head);獲取尾部(除去第一個元素以外的元素:slPeople.tail)

                                          向列表頭添加新的元素從而生成新的列表:val  slNewList="趙四"::slPeople(不能給列表的尾添加元素)

                                         

 

                      Range(隊列):是一種特殊的帶索引的不可變數字等差序列(range內可以存放任何類型數據)

 

                                           定義:val irNum=new Range(n1,n2,m):與Python的range函數功能相同,n1(開始量)n2(結束量,取不到)m(步長)

 

                                            1 to  8  by 1:得到包括8的Range(1,8,1)序列

                                            1 until 8  by 1:得到Range(1,8,1)序列

                                        

       IndexedSeq:Vector和ArrayBuffer可以繼承該類

 

                         Vector(向量):

 

                                               定義:val svPeople=Vector("張三","李四","王五"......)

 

                                               獲取元素svPeople(n):獲取第n+1個元素

                                               向Vector的頭添加元素:svPeople1="趙四"+:"錢七"+:svPeople;向Vector的尾添加元素:val svPeople2=svPeople:+"孫八"

                                         

 

(5)定義集合Set:存放不重復元素,沒有先后順序,用哈希方法去查找元素(默認為不可變集合)

 

                    可變集:(導包scala.collection.mutable)

 

                    不可變集:(導包scala.collection.immutable)

import scala.util.control.Breaks._;
import scala.collection;
import scala.collection._;
import scala.collection.immutable._;   
var ssPeople=Set("張三","李四");     //Set("張三","李四")是不可變集,將不可變集賦給可變變量ssPeople
ssPeople+="王五";                   //將"王五"賦加給變量ssPeople后生成新的不可變集Set("張三","李四","王五")
import scala.collection.mutable._;    //要定義可變集必須導入這個包
val ssPeople1=Set("張三","李四");      //Set("張三","李四")是可變集,
ssPeople1+="王五";

                 

(6)定義映射Map:一系列鍵值對的容器,鍵唯一但值不唯一(默認為不可變映射)

                    可變映射:(導包scala.collection.mutable)

                    不可變映射:(導包scala.collection.immutable)

import scala.util.control.Breaks._;
import scala.collection;
import scala.collection._;
import scala.collection.immutable._;
var ssPeople=Map("姓名:"->"張三","年齡:"->16);     //不可變映射
import scala.collection.mutable._;    //要定義可變集必須導入這個包
val ssPeople1=Map("姓名:"->"張三","年齡:"->16);     //Set("張三","李四")是可變映射,
ssPeople1+=("性別"->"男","學號:"->20173522);   //向可變映射中添加多個元素
ssPeople1("姓名:")="李四";      //更新可變映射中的元素
ssPeople1("學校:")="石家庄鐵道大學";    //向可變映射中添加單個元素
print("查詢姓名");
var result=if(ssPeople1.contains("姓名:"))  ssPeople1("姓名:")  else  "無法查詢姓名"  //當映射中存在鍵為"姓名:"則將對應的值賦給result,否則將無法查詢xx賦給result
print(s"姓名:$result");

              

二,輸入,輸出

     1,從控制台輸入(導包:scala.io.StdIn):

         

      2,輸出(默認導包scala.Predef):

          (1)類Java的輸出方式: print("姓名:"+name+"\t年齡:"+age)或println("姓名:"+name+"\t年齡:"+age)

         

          (2)類C的輸出方式:printf("姓名:%s\t年齡:%s",name,age)

        

         (3)s插值字符串輸出法:print(s"姓名:$name\t年齡:$age")

        

         (4) f插值字符串輸出法(格式化):

        

三,讀寫文件(導包java.io.PrintWriter和scala.io.Source)

       1,寫入(導包java.io.PrintWriter):向文件test.txt中寫入信息:

           

          

       2,讀取(導包scala.io.Source):

         

四,控制結構

     1,for結構:

        用法一:基本結構

            

         用法二:for結構中加條件

               

         用法三:支持多個生成器,用;隔開 

       

        用法四:將遍歷的值付給變量

       

      

   2,異常處理(try......catch.....)

   3,循環控制(不存在break和continue終止循環)

        使用Breaks類(導包scala.util.control)

       當使用breakable方法:

import scala.util.control.Breaks._;
var i=0;
val array=Array(1,3,6,15,9,12,16);
breakable{      //這個大括號不能換行
    for(i<-array)
    {
        if(i>10) break;   //循環到15直接跳出循環
        print(i+"\t");
    }
}

      

   4,判斷值是否存在:contains()

五,類

    1,定義方法:當有返回值,則返回String,Int,Boolean;無返回值,則返回Unit類型

        

         參數列表中的參數不能用val,var修飾

          參數列表沒有時,可以不用()

          (參數列表)可以寫成{參數列表};當只有一個參數時,可以用中綴調用法

         

          當方法體只有一條語句,可以省略{}

import scala.util.control.Breaks._;
class Conent{      //不能換行
    var value=0;
    def dIncrement(s:Int):Unit={
        value+=s;
    }
    def dCurrent():Int={
        value;
    }
}
val conent=new Conent;
conent.value=5;
conent.dIncrement(2);
print(conent.dCurrent);

     2,類似Java的get,set方法:value方法相當於Java的Getxx方法,獲取類中的變量的值;value_方法相當於Java的Setxx方法,修改類中變量的值。

import scala.util.control.Breaks._;
import scala.io.StdIn;
class Student{
    private var pvsName="";
    private var pviAge=0;
    def valueName=pvsName;
    def valueName_=(newName:String){
        pvsName=newName;
    }
    def valueAge=pviAge;
    def valueAge_=(newAge:Int){
        if(newAge>0 &&newAge<200){
              pviAge=newAge;
        }
    }
}
val students=new Student;
printf("請輸入姓名:");
var sname=readLine();
students.valueName_=(sname);
printf("請輸入年齡:")
var iage=readInt();
students.valueAge_=(iage);
printf("學生姓名:%s \t 學生年齡:%d",students.valueName,students.valueAge);

六,構造器

      主構造器:scala可以定義帶參數的類作為一個主構造器,可以給這個類之間傳參,改變參數值,輸出參數值

    

 

 

     輔助構造器:調用形式:this(參數列表)

    

 

 

 

import scala.util.control.Breaks._;
import scala.io.StdIn;
class Student{
    var sName="";
    var age=0;
    println("這是主構造器;");
    def this(sName:String){                       //第一個輔助構造器
        this();                                        //調用主構造器
        this.sName=sName;
        print(s" 這是第一個輔助構造器;姓名:$sName\n");
    }
    def this(sName:String,age:Int){           //第二個輔助構造器
        this(sName);                            //調用第一個輔助構造器
        this.age=age;
        print(s" 這是第二個輔助構造器;姓名:$sName \t 年齡:$age\n");
    }
}
var getStudent=new Student("張三");                //執行第一個輔助構造器
var getStudent=new Student("張三",17);          //執行第二個輔助構造器

運行結果:

      

 

 

 (七)對象

   

 

 

 1,單例對象:1,定義,使用object定義;object 對象名{ 內容}

                   2,對象內的所有字段和方法都是靜態的,不用對對象的進行實例化。

                   3,分類:伴生對象和孤立對象

     1,伴生對象:當類名和單例對象名一樣且定義在一個scala代碼文件中,則彼此可以訪問對方的成員

        

 

 

     2,孤立對象:一個scala代碼文件內類名和單例對象名都不相同,則這個單例對象稱為孤立對象,

2,apply方法:不斷創建對象,自動調用(工廠方法);例如創建數組時,直接val array=Array(“張三”,"李四"),會自動調用apply方法。

                   當要調用的類中定義了apply方法,則不用手動調用apply方法,程序會自動調用該方法。

                   將面向對象編程(調用方法:對象.方法(參數))和函數式編程(方法(參數))結果一致,都可以使用

                   對象調用可以轉換為函數調用;函數調用可以轉換為對象調用

 

 

         

 

 

 例子:使用伴生對象,伴生類和apply方法

import scala.io.StdIn;
class Student(name:String,age:Int){
    def Test():Unit={
        print(s"姓名:$name,年齡:$age\n");
    }
}
object Student{
    def apply(name:String,age:Int)=new Student(name,age);    //調用伴生類的構造方法
}
object Main{
    def main(args: Array[String]): Unit = {
      println("請輸入姓名:");
      var name=readLine();
      println("請輸入年齡:");
      var age=readInt();
      var student=Student(name,age);                //調用伴生對象的apply方法
      student.Test();
    }
    
}

      運行結果:

     

 

 

 3,update方法:根據對象名取出對象的參數;要使用對象參數時調用。

 

 

 (八)類的繼承

         1,抽象類:類的成員沒有被實例化,用abstract修飾;

                             在抽象類中可以定義有方法體,被實現的方法

                             抽象類中的成員,方法不用abstract修飾;但抽象的變量必須聲明類型:val name:String;

        2,繼承類:必須加extends關鍵字;

                           子類只能重載val變量

                           如果父類中的變量已經賦值,子類調用父類變量則要加override,如果父類中的變量沒有賦值,子類調用父類變量則可以不加override

       3,option類:抽象類,對象:Some對象(返回不為空時,封裝到該對象)和None對象(返回為空時)

                  

 

         

 

         

 

          4,特質:有Java的接口功能,但可以在特質中定義有方法體的方法;關鍵字:trait

                      特質中定義抽象方法可以不用abstract關鍵字

                      特質可以繼承特質

                     一個類可以混入多個特質,關鍵字:extends 特質名1  with  特質名2

          5,模式匹配:

            1,類似switch()..case:...:不需要break退出

var grade=readChar();
grade match {
    case 'A' =>println("85-100");
    case 'B' =>println("75-84");
    case 'C' =>println("60-74");
    case 'D' =>println("30-59");    
    case _=> println("對不起,你輸錯了")
}

            例子:case可以判斷數據類型                                                                                        case后可以加入判斷

               

 

          2,case類:自動重載多個有用對象,自動創建伴生對象(apply方法和unapply方法)。

     6,包:可以嵌套定義。

(九)函數:

         1,定義:

                     

 

         2,函數字面量:

                      函數類型和值:

                            

                      類型:                

                      值: 

 

         3,另一種定義函數方式:函數式變量可以調用,可以賦給其他變量(函數名counter可以省略,匿名函數又稱Lambda表達式)

               當函數中變量只出現一次,可以用_占位

                             

 

                            

 

                            

 

           4,高階函數:函數的一個參數為另一個函數

                           

 

 (十)對容器操作:

          1,遍歷操作:foreach方法:容器名.foreach(參數)

                  例子:變量映射:

              

              

 

         2,映射操作:

                例如:對容器元素進行一對一映射操作;關鍵操作函數:map(具體操作方法)

             

 

              將得到的三個結果容器拍扁成為一個容器;關鍵操作函數:flatMap(具體操作方法)

             

 

         3,過濾操作:關鍵操作函數:filter(具體過濾操作)

                例如:將Map中值含有"三"的鍵值對留下:

               

 

               

 

        4,歸約操作:關鍵操作函數:reduce(具體操作)

               

                 歸約函數使用了s插值輸出方式

               

 

      使用fold方法,可以賦初始值;

               

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM