(一)SCALA基本文法:
(1)Scala有兩種類型的變量
Val:不可變,聲明的時候就被初始化,且不可再被指派
Var: 聲明的時候需要進行初始化,還可以再次對其指派
Scala預設導入Java.lang._
scala> val mystr = “Hello
World”
val mystr: String = Hello World
scala> val myStr2 : String = “Hello
World”
val myStr2: String = Hello World
scala> val myStr3 : java.lang.String =
“Hello World”
val myStr3: String = Hello World
scala> print(mystr,myStr2,myStr3)
(Hello World,Hello World,Hello World)
scala> myStr2 = “Hello sclaa”
^
error: reassignment to val
(2)操作符 + - * / %
scala> val sum1 = 5+3
val sum1: Int = 8
等價:
scala> val sum2 = (6). + (2)
val sum2: Int = 8
(3)和Java不同,Scala沒有++、–遞增遞減操作符,但是可以使用:
scala> var i = 5;
var i: Int = 5
scala> i += 1
scala> print(i)
6
(3)、富包裝類scala.runtime中,Scala自動通過隐式轉換将對象轉換為對應的富包裝類型
(4)、Range
For循環,i的值從m到n,用range實作,支援Int,Long,Float,Double,Char,BigInt,BigDecimal等。
scala> 1 to 5
val res2:
scala.collection.immutable.Range.Inclusive = Range 1 to 5
scala> 1 until 5
val res4: scala.collection.immutable.Range
= Range 1 until 5
scala> 1 to 5 by 2
val res0: scala.collection.immutable.Range
= Range 1 to 5 by 2
(5)、控制台讀寫資料:
所有的基本資料類型都屬于對象scala.io.StdIn的方法,使用前必須導入,或者使用全稱調用
scala> import io.StdIn._
import io.StdIn._
scala> var i=readInt()
52
var i: Int = 52
scala> var f=readBoolean()
false
var f: Boolean = false
scala> var str=readLine(“Please
input your name:”)
Please input your name:niubi
var str: String = niubi
Scala還支援C語言風格
print()、println()、printf()在Predef中定義好的,直接用
(6)寫入檔案
Scala需要使用Java.io.PrintWriter實作把資料寫入檔案
scala> import java.io.PrintWriter
import java.io.PrintWriter
scala> val out = new
PrintWriter(“output.txt”)//在哪裡啟動的Scala指令,就寫到哪裡
val out: java.io.PrintWriter =
[email protected]
scala> for (i <- 1 to 5)
out.println(i)
scala> out.close()
(7)、使用scala.io.Source的getLines方法實作對檔案讀取
scala> import scala.io.Source
import scala.io.Source
scala> val inputFile =
Source.fromFile(“output.txt”)
val inputFile: scala.io.BufferedSource =
scala> val lines = inputFile.getLines
val lines: Iterator[String] =
scala> for (line <- lines)
print(line)
12345
(7)異常處理
Scala不支援Java中的受檢查的異常,但仍使用try-catch捕獲異常
(二)Scala控制結構
If循環:
scala> val x = 6
val x: Int = 6
scala> if (x>0){println(“This is
a positive number”)
| } else {
| println(“This is not a positive number”)
| }
This is a positive number
While 循環:
scala> while (i>0){
| i -= 1
| printf(“i is %d\n”,i)
| }
i is 8
i is 7
i is 6
i is 5
i is 4
i is 3
i is 2
i is 1
i is 0
for 循環(比那輛<-表達式)稱為生成器:
scala> for (i <- 1 to 5) print(i)
12345
scala> for (i <- 1 to 5 by 2)
print(i)//增加步長
135
for (i <- 1 to 5 if i%2==0) print(i) //隻輸出偶數
24
Scala多個生成器示例:
scala> for (i <- 1 to 5;j<- 1 to
3) print(i*j)//println分行
123246369481251015
scala> for (i <- 1 to 5 if
i%2==0;j<- 1 to 3) println(i*j)
2
4
6
4
8
12
For推導式:
https://blog.csdn.net/wanghao_0206/article/details/53495894
(三)Scala資料結構
容器、清單、集合、映射、疊代器、數組、元組
有序無序 可變不可變
Scala用了三個包組織容器類,scala.collection、scala.collection.mutable、scala.collection.immutable。
清單是不可變集合,定義在scala.collection.immutable包中。聲明List時必須初始化。
Var strList = List(“BIGDATA”,”Hadoop”,”Spark”)
清單頭部-head\尾部-tail。Head傳回清單第一個元素的值。Tail傳回出第一個元素,其他值構成的遞歸的新連結清單結構。
scala> var
strList=List(“BigData”,“Hadoop”,“Spqrk”)
var strList: List[String] = List(BigData,
Hadoop, Spqrk
scala> strList.head
val res0: String = BigData
scala> strList.tail
val res1: List[String] = List(Hadoop,
Spqrk)
在已有清單前端增加元素 ::
scala> val otherList =
“Apacge”::strList
val otherList: List[String] = List(Apacge,
BigData, Hadoop, Spqrk)
集合:可變和不可變,位于scala.collection.mutable和scala.collection.immutable.
scala> var mtSet =
Set(“Hadoop”,“Spark”)
var mtSet:
scala.collection.immutable.Set[String] = Set(Hadoop, Spark) //var可變
scala> mtSet += “Scala” //增加新的元素
scala> mtSet
val res4: scala.collection.immutable.Set[String]
= Set(Hadoop, Spark, Scala) //新的清單
聲明可變集
scala> val myMutableSet =
Set(“Database”,“BigData”)
val myMutableSet:
scala.collection.mutable.Set[String] = HashSet(Database, BigData)
scala> myMutableSet += “Cloud
Computing”
val res5: myMutableSet.type =
HashSet(Database, BigData, Cloud Computing)
映射:Map是一系列鍵值的容器,鍵是唯一的值不一定唯一,根據鍵值進行檢索。Scala.collection.mutable(可變)和scala.collection.immutable(不可變)裡
scala> val university =
Map(“XMU”->“Xianmen University”,“THU”->“Tsinghua
University”,“PKU”->“Peking University”)
val university:
scala.collection.immutable.Map[String,String] = Map(XMU -> Xianmen
University, THU -> Tsinghua University, PKU -> Peking University)
scala>
println(university(“XMU”))
Xianmen University
如果給定的鍵不存在,則會抛出異常,可以先調用contains方法确定鍵是否存在
scala> val xmu =
if(university.contains(“XMU”)) university(“XMU”) else 0
val xmu: Any = Xianmen University
scala> println(xmu)
Xianmen University
循環周遊映射:for ((k , v)<-映射)
cala> for((k,v)<-university)
printf(“Code is : %s and name is: %s\n”,k,v)
Code is : XMU and name is: Xianmen
University
Code is : THU and name is: Tsinghua
University
Code is : PKU and name is: Peking
University
疊代器(iterator)
在Scala中,疊代器不是集合,但是提供通路集合的一種方法。
疊代器操作:next 和
hasNext。Next傳回下一個元素,hasNext檢測是否還有下一個元素。
scala> val iter =
Iterator(“Hadoop”,“Spark”,“Scala”)
val iter: Iterator[String] =
scala> while(iter.hasNext){
| println(iter.next())
| }
Hadoop
Spark
Scala
scala> val iter = Iterator(“Hadoop”,“Spark”,“Scala”)
val iter: Iterator[String] =
scala> for (elem<- iter){
| println(elem)
| }
Hadoop
Spark
Scala
數組:
數組是可變、索引、元素相同類型的資料集。Scala提供Array[T]。
cala> val intValueArr = new
ArrayInt //聲明一個長度3的整型數組
val intValueArr: Array[Int] = Array(0, 0,
0)
scala> intValueArr(0) = 11 //指派
scala> intValueArr(1) = 22
scala> intValueArr(2) = 33
scala> for (i <- 0 to 2)
println(intValueArr(i)) //列印數組
11
22
33
scala> val myStrArr = new
ArrayString //定義長度為三的字元串
val myStrArr: Array[String] = Array(null,
null, null)
scala> myStrArr(0) = “ZHAO”
scala> myStrArr(1) = “GUO”
scala> myStrArr(2) = “Zhang”
scala> for (i <- 0 to 2)
println(myStrArr(i))
ZHAO
GUO
Zhang
Array
類型 定義的數組是定長數組,他的數組長度初始化後就不能改變。定義變長數組:ArrayBuffer,位于scala.collection.mutable。
scala> import
scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
scala> val aMutableArr =
ArrayBuffer(10,20,30)
val aMutableArr: scala.collection.mutable.ArrayBuffer[Int]
= ArrayBuffer(10, 20, 30)
scala> aMutableArr += 40
val res25: aMutableArr.type =
ArrayBuffer(10, 20, 30, 40)
scala> aMutableArr -= 40
val res28: aMutableArr.type =
ArrayBuffer(10, 20, 30)
scala> var temp = aMutableArr.remove(2)
var temp: Int = 30
元組是不同類型的值的聚集。而清單的各個元素必須相同類型。
scala> val tuple =
(“BigD”,“1”,“No1”)
val tuple: (String, String, String) = (
BigD ,1 ,No1)
(四)面向對象———類、對象、繼承、特質、模式比對
類的定義 和 編譯執行
簡單的類:class Counter{‘’’’’’字段’’’’’}
New關鍵詞生成:new Counter // or //
new Counter()
scala>
class Counter{
| private var value = 0
| def increment():Unit ={ value += 1}
| def current():Int = {value}
|
| }
class
Counter
//Unit後面的等号和大括号,包含該方法要執行的具體操作語句
建立TestCounter.scala代碼檔案
[email protected]:~/scala$
vi TestCounter.scala
寫入:
class
Counter{
private var value = 0
def increment():Unit = {value += 1}
def current():Int = {value}
}
val
myCounter = new Counter
myCounter.increment()
println(myCounter.current)
[email protected]:~/scala$
scala TestCounter.scala//運作
1
用scalac
TestCounter.scala編譯會出現錯誤,原因:聲明都沒有被封裝在對象中,是以無法編譯成jvm位元組,編寫Test CounterJVM.scala檔案vi TestCounterJVM
class
Counter{
private var value = 0
def increment():Unit = {value += 1}
def current():Int = {value}
}
object
MyCounter{
def main(args:Array[String]){
val myCounter = new Counter
myCounter.increment()
println(myCounter.current)
}
}
[email protected]:~/scala$
scalac TestCounterJVM.scala
warning:
1 deprecation (since 2.13.0); re-run with -deprecation for details
1
[email protected]:~/scala$
scala MyCounter //MyCounter是包含main方法的對象名稱。
1
接着改進,讓方法中帶有參數,修改TestCounterJVM檔案。
[email protected]:~/scala$
vi TestCounterJVM.scala
class
Counter{
private var value = 0
def increment(step:Int):Unit = {value +=
step}
def current():Int = {value}
}
object
MyCounter{
def main(args:Array[String]){
val myCounter = new Counter
myCounter.increment(5)
println(myCounter.current)
}
}
[email protected]:~/scala$
scalac TestCounterJVM.scala
warning:
1 deprecation (since 2.13.0); re-run with -deprecation for details
1 warning
[email protected]:~/scala$
scala MyCounter
類getter和setter方法
類中的字段設定值以及讀取值在Java中式getter、setter實作的,Scala也是,但是沒有定義成getxxx\setxxx.
修改TestCounterJVM.scala檔案
class
Counter{
var value = 0//沒有修飾符,外部可見
def increment(step:Int):Unit = {value +=
step}
def current():Int = {value}
}
object
MyCounter{
def main(args:Array[String]){
val myCounter = new Counter
println(myCounter.value)//不是用getxxx擷取字段的值
myCounter.value = 3//不是setxxx設定字段的值
myCounter.increment(1) //設定步長為1
println(myCounter.current)
}
}
[email protected]:~/scala$
scalac TestCounterJVM.scala //編譯
warning:
1 deprecation (since 2.13.0); re-run with -deprecation for details
1 warning
[email protected]:~/scala$
scala MyCounter//執行
4
提示:若定義private value 會出現error.
Value 變成私有字段,Scala沒有提供getter和setter方法,要想通路value,定義value
Private
var privateValue = 0
def value
= private
def
value_ = (newValue:Int){
if(newValue > 0) privateValue = newValue
}
構造器
Scala構造器包含1個主構造器和若幹個輔助構造器
輔助構造器的名稱this,每個輔助構造器都必須調用此前定義的主或輔助構造器
定義一個帶有輔助構造器的類:
構造器最大的構造器最大的用處就是在建立對象時執行初始化,當建立一個對象時,系統會為這個對象的執行個體進行預設的初始化。如果想改變這種預設的初始化,就可以通過自定義構造器來實作。用處就是在建立對象時執行初始化,當建立一個對象時,系統會為這個對象的執行個體進行預設的初始化。如果想改變這種預設的初始化,就可以通過自定義構造器來實作。
class
Counter{
private var value = 0
private var name = “”
private var mode = 1
def this(name:String){
this()
this.name = name
}
def this(name:String,mode:Int){
this(name)
this.mode = mode
}
def increment(step:Int):Unit = {value +=
step}
def current():Int = {value}
def info():Unit = {printf(“Name:%s and
%d\n”,name,mode)}
}
object
MyCounter{
def main(args:Array[String]){
val myCounter1 = new Counter
val myCounter2 = new
Counter(“Runner”)
val myCounter3 = new
Counter(“Timer”,2)
myCounter1.info
myCounter1.increment(1)
printf(“Current Value is :
%d\n”,myCounter1.current)
myCounter2.info
myCounter2.increment(2)
printf(“Current Value is :
%d\n”,myCounter2.current)
myCounter3.info
myCounter3.increment(3)
printf(“Current Value is : %d\n”,myCounter3.current)
}
}
[email protected]:~/scala$
scala MyCounter
Name: and
1
Current
Value is : 1
Name:Runner
and 1
Current
Value is : 2
Name:Timer
and 2
Current
Value is : 3
單例對象和伴生對象
Scala可以采用關鍵字object來實作單例對象,和Java靜态方法具有同樣的功能。
單例對象的定義和類的定義很相似,但是用的是object關鍵字而不是class。
單例對象:
object
Person{
private var lastId = 0
def newPersonId()={
lastId += 1
lastId
}
}
printf(“The
first person id is %d.\n”,Person.newPersonId())
printf(“The
second person id is %d.\n”,Person.newPersonId())
printf(“The
third person id is %d.\n”,Person.newPersonId())
運作
[email protected]:~/scala$
scala Person.scala
The first
person id is 1.
The
second person id is 2.
The third
person id is 3.
Apply\update方法
用括号傳遞給變量一個或多個參數時,Scala會把它轉換為對apply方法的調用
在類中定義apply方法:
class
TestApplyClass {
def apply(param:String): String = {
println(“apply method called,parameter
is:” + param)
“Hello World!”
}
}
val
myObject = new TestApplyClass
println(myObject(“param1”))
運作test.scala
[email protected]:~/scala$
scala test.scala
apply
method called,parameter is:param1
Hello
World!
也可以在單例對象中定義apply.
繼承
Scala不允許類從多個超類繼承
abstract
class Car{
val carBrand: String
def info()
def
greeting(){println(“Welcome,zaza”)}
}
class
BMWCar extends Car{
override val carBrand = “BMW”
def info(){println(“This is a %s car.It
is expensive.\n”,carBrand)}
override def greeting()
{println(“welcome to my car~~”)}
}
class
BYDCar extends Car{
override val carBrand = “BYD”
def info() {printf(“This is a %s car.It
is expensive.\n”,carBrand)}
override def greeting()
{println(“welcome to my BYD car~~”)}
}
object
MyCar{
def main(args:Array[String]){
val myCar1 = new BMWCar()
val myCar2 = new BYDCar()
myCar1.greeting()
myCar1.info()
myCar2.greeting()
myCar2.info()
}
}
[email protected]:~/scala$
scala car.scala
warning:
7 deprecations (since 2.13.0); re-run with -deprecation for details
welcome
to my car~~
(This is
a %s car.It is expensive.
,BMW)
welcome
to my BYD car~~
This is a
BYD car.It is expensive.