一,變量
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方法,可以賦初始值;