Scala基於JVM的程式語言
阿新 • • 發佈:2018-11-11
一、Scala簡介
Scala是將面向物件和面向函式式整合在一起,基於JVM的程式語言。它由Martin Odersk於2001開發,2004年開始執行在JVM與.Net平臺之上,由於其簡潔、優雅、型別安全的程式設計模式而受到關注。
Scala六個特徵:
- Java和scala可以無縫混編(因為都是基於JVM的程式語言)
- 型別推測(自動推測型別)
- 併發和分散式(Actor)
- 特質trait,特徵(整合java中介面和抽象類的優點)
- 模式匹配(類似於java中的switch)
- 高階函式(函式的引數是引數,函式的返回是函式)
二、Scala基礎
1、資料型別:
Byte、Short、Int、Long、Float、Double、Char、String、Boolean。這些跟JAVA中等同。
- Unit:表示無值,和java中的void等同
- Null:空值或空引用
- Nothing:其他型別的子類,表示沒有值
- Any:所有型別的超類,任何例項都屬於Any型別,類似於JAVA中的Object
- AnyRef:所有引用型別的超類
- AnyVal:所有值型別的超類
2、變數和常量的宣告
變數:用var定義,可修改
常量:用val定義,不可修改
當引數沒有修飾,那麼外部無法通過物件來呼叫,類似於JAVA中的private。
var name = "zhangsan"
val gender = "男"
3、類和物件
伴生類:
class Person{
val name = "zhangsan"
val age = 18
def sayName() = {
"my name is "+ name
}
}
伴生物件:
object Lesson_Class { def main(args: Array[String]): Unit = { val person = new Person() println(person.age); println(person.sayName()) } }
總結:
- 建構函式和JAVA不一樣,直接類名後加引數
- 伴生類中主要宣告動態屬性,伴生物件主要宣告靜態屬性。
4、if else判斷體
- if else
- if else if else
5、迴圈體
for迴圈
- 通過索引
- 增強for迴圈
- 雙重迴圈
- 帶有判斷條件
- yield
while迴圈
do while迴圈
總結:
- yied關鍵詞能夠將符合要求的元素自動封裝到一個集合中
- 1 to 10包括10,1 until 10不包括10
- scala中不能使用count++,只能使用count = count+1
- 在scala中沒有break跳出迴圈,可設定標記,例如var flag = true
6、函式
1.普通函式(有參函式、無參函式)
def fun (a: Int , b: Int ) : Unit = {
println(a+b)
}
fun(1,1)
def fun1 (a : Int , b : Int)= a+b
println(fun1(1,2))
2.遞迴函式:在函式體內呼叫自己本身
// 計算num的階乘
def fun1(num:Int):Int = {
if(num == 1||num == 0) 1
else num * fun1(num - 1)
}
3.預設值的函式
def fun2(num1:Int = 10,num2:Int = 20) = {
num1 + num2
}
def fun3(num1:Int,num2:Int = 20) = {
num1 + num2
}
def fun4(num1:Int=10,num2:Int) = {
num1 + num2
}
4.可變引數個數的函式
def fun4(elements :Int*)={
var sum = 0;
for(elem <- elements){
sum += elem
}
sum
}
println(fun4(1,2,3,4))
5.匿名函式
var fun6 = (num1:Int,num2:Int) => num1+ num2
6.巢狀函式
def fun7(num:Int)={
def fun8(a:Int,b:Int):Int={
if(a == 1){
b
}else{
fun8(a-1,a*b)
}
}
fun8(num,1)
}
7.偏應用函式
偏應用函式是一種表示式,不需要提供函式需要的所有引數,只需要提供部分,或不提供所需引數。
def log(date:Date,content:String) = {
println("date:" + date + "\tcontent:" + content)
}
val date = new Date()
log(date,"log1")
log(date,"log2")
log(date,"log3")
println("==============================")
val logBoundDate = log(date,_:String)
logBoundDate("log11")
logBoundDate("log12")
logBoundDate("log13")
8.高階函式
函式的引數是函式,或者函式的返回型別是函式,或者函式的引數和函式的返回型別都是函式的函式。
/**
* 函式的引數是函式:
* f1:(Int)=>Int 告訴要傳入的函式的格式
* 把函式當成了物件穿來穿去、scala支援面向函式程式設計
*/
def highFun1(f1:(Int)=>Int,num:Int) = {
f1(num)
}
def tmpFun(num1:Int) = {
num1+1000
}
/**
* 函式的返回是函式
* 函式無引數
* 函式的返回個(Int,Int)=>Double格式的函式
*/
def highFun2():(Int,Int)=>Double = {
def tmpFun2(num1:Int,num2:Int):Double = {
num1 + num2
}
tmpFun2
}
def highFun3():(Int,Int)=>Double = {
(num1:Int,num2:Int)=>num1+num2
}
/**
* 函式是引數是函式,返回也是函式
* 這個函式也是高階函式
*/
def highFun4(f1:(Int,Int) => Int,num1:Int):(Int)=>Double = {
val rest = f1(num1,1000)
(num:Int) => num + 1
}
def highFun5(num:Int):(Int)=>Int = {
def fun(a:Int)={
num + a
}
fun
}
9. 柯里化函式
可理解為對高階函式的簡化
def klhFun(a:Int)(b:Int) = a*b
Scala語言的簡寫規則:
- 函式的返回值型別可以省略,因為scala具備自動推測的功能,他會根據返回值的自動來決定這個函式的返回值型別
- 將你要返回的值放在函式的最後一行,那麼這個值就會被自動返回
- 如果你的函式體內只有一個語句,可以將這行語句與函式名在一行。
總結:
- 對於遞迴函式 必須明確返回值型別,不然不知所措;
- 預設值的函式中,如果傳入的引數個數與函式定義相同,則傳入的數值會覆蓋預設值;如果不想覆蓋預設值,傳入的引數個數小於定義的函式的引數,則需要指定引數名稱;
- 在scala中+=前後的數值型別必須一致,+前後的數值型別可以不一致;
- 注意點:
1)匿名函式不能顯示的宣告返回值型別
2)匿名函式必須賦給一個變數、變數,通過變數來呼叫這個匿名函式
3)匿名函式的引數與函式體必須要用=>來關聯
7、集合
1.Array
/**
* 建立陣列的兩種方式:
* 1.new Array[String](3)
* 2.直接Array
*/
//建立型別為Int 長度為3的陣列
val arr1 = new Array[Int](3)
//建立String 型別的陣列,直接賦值
val arr2 = Array[String]("s100","s200","s300")
//賦值
arr1(0) = 100
arr1(1) = 200
arr1(2) = 300
/**
* 建立二維陣列
*/
val secArray = new Array[Array[String]](10)
for(index <- 0 until secArray.length){
secArray(index) = new Array[String](10)
}
/**
* 遍歷陣列的兩種方式
*/
for(i <- arr1){
println(i)
}
arr1.foreach(i => {
println(i)
})
for(s <- arr2){
println(s)
}
arr2.foreach {
x => println(x)
}
2.List
//建立List 不可變List
val list = List(1,2,3,4,5)
//遍歷List
list.foreach { x => println(x)}
// list.foreach { println}
// filter方法
val list1 = list.filter { x => x>3 }
list1.foreach { println}
// count方法
val value = list1.count { x => x>3 }
println(value)
// map
val nameList = List(
"hello bjsxt",
"hello xasxt",
"hello shsxt"
)
val mapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }
mapResult.foreach{println}
// flatmap 先map再flat
val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }
flatMapResult.foreach { println }
/**
* 可變的list集合
*/
val listBuffer = new ListBuffer[String]
listBuffer.+=("hello")
listBuffer.+=("bj")
listBuffer.foreach { println }
listBuffer.-=("hello")
3.Set
//建立Set
val set1 = Set(1,2,3,4,4)
val set2 = Set(1,2,5)
//遍歷Set集合
//注意:set會自動去重
set1.foreach { println}
for(s <- set1){
println(s)
}
4.Map
val map = Map(
"1" -> "bj",
2 -> "sh",
3 -> "gz"
)
val keys = map.keys
val keyIterator = keys.iterator
while(keyIterator.hasNext){
val key = keyIterator.next()
/**
* map集合的get方法返回值是一個Option型別的物件
* Option型別有兩個子型別 分別為some None
*/
println(key + "\t" + map.get(key).get)
}
/**
* getOrElse原理:去集合中去取資料,若不存在返回預設值
*/
println(map.get(4).getOrElse("default"))
// Map遍歷
for(k <- map)
println(k._1 + "\t" + k._2)
map.foreach(x=>println(x._1 + "\t" + x._2))
// filter:過濾,留下符合條件的記錄
map.filter(x=>{
Integer.parseInt(x._1 + "") >= 2
}).foreach(println)
// count:統計符合條件的記錄數
val count = map.count(x=>{
Integer.parseInt(x._1 + "") >= 2
})
println(count)
5.Tuple
/**
* 元組 vs list
* list建立的時候指定了泛型,那麼集合中必須是這個泛型的物件
* 元祖中可以包含任意型別的元素,這些元素使用一對小括號來封裝
* 元組的建立:最多支援22個
*/
val t2 = Tuple2(1,"hello")
val tt2 = (1,"hello")
val t3 = Tuple3(1,true,"hello")
val tt3 = (1,true,"hello")
val moreTuple = (1,2,3)
// 元組的遍歷
val tupleIterator = tt3.productIterator
while(tupleIterator.hasNext){
println(tupleIterator.next())
}
// toString方法
println(tt3.toString())
//swap交換 注意只有二元組物件才會有這個方法
val swapt2 = tt2.swap
println(swapt2._1 + "\t" + swapt2._2)
8、字串
// String不可變
val str1 = "hello bi"
val str2 = "hello sh"
val flag = str1.equalsIgnoreCase(str2)
println(flag)
str1.split(" ")
// StringBuffer可變
val strBuilder = new StringBuilder
strBuilder.append("hello\t")
strBuilder.append("bj")
println(strBuilder)
總結:
9、Trait特性
Scala相當於JAVA中的介面但是他比介面功能更加強大,與介面不同的是它還可以定義屬性和方法的實現。
Trait可以繼承多個Trait,也就是多繼承,Trait定義的方式與類相似,使用關鍵字trait。