Scala學習記錄01

一鴨一鴨呦呦發表於2020-09-26

1.scala和java

-------javascala
字串Java需要採用“+”進行字串的連線scala採用三個雙引號“”“支援換行字串
方法和返回值returnscala的return是可選的,方法呼叫會自動返回最後求值的表示式。如果scala使用了return則需要顯示指定方法的返回值
類和方法修飾的預設值protectedproblic
預設匯入的類java.langscala預設匯入java.lang包、scala包、scala.Predef類
介面支援介面:interface不支援介面,有類似抽象類的:Trait
類成員和單例物件java由類成員,單例物件需要自己實現scala語言機制上支援單例物件和伴生物件,伴生類。伴生類和伴生物件需要在一個類檔案中使用,在使用伴生物件時,系統隱式地呼叫apply生成一個伴生例項的物件。

2.資料型別和操作符

scala中的資料型別每一個都是一個類,scala會自己負責基本資料型別和引用型別的轉換操作。因此使用上面的資料型別可以直接呼叫相關函式.

3. 宣告值和變數

Scala宣告變數有2種方式,var和val:
val定義的是不可變的變數,,稱為只讀變數
var:是可讀變數,
scala預設匿名變數分配val

4.類結構圖:

[類圖](https://img-blog.csdnimg.cn/2020092609191347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbmF0XzQyMjgzMzc4,size_16,color_FFFFFF,t_70#pic_center)
Scala中,所有的值都是類物件,而所有的類,包括值型別,都最終繼承自一個統一的根型別Any。統一型別,是Scala的又一大特點。更特別的是,Scala中還定義了幾個底層類(Bottom Class),比如Null和Nothing。

5.算術操作符的過載

+-*/%可以完成和Java中相同的工作,但是有一點區別,他們都是方法。你幾乎可以用任何符號來為方法命名。 
舉例:	
scala> 1 + 2
等同於:
scala> 1.+(2)

6.for 表示式

//to左右兩邊為前閉後閉的訪問
for(i <- 1 to 3; j <- 1 to 3){
  print(i * j + " ")
}
//until左右兩邊為前閉後開的訪問
for(i <- 1 until 3; j <- 1 until 3) {
  print(i * j + " ")
}
println()
//引入保護式(也稱條件判斷式)該語句只列印1 3。保護式滿足為true則進入迴圈內部,滿足為false則跳過,類似於continue
for(i <- 1 to 3 if i != 2) {
  print(i + " ")
}
println()
//引入變數
for(i <- 1 to 3; j = 4 - i) {
  print(j + " ")
}
println()
//將遍歷過程中處理的結果返回到一個,使用yield關鍵字
val for5 = for(i <- 1 to 10) yield i
println(for5)
//使用花括號{}代替小括號()
for{
  i <- 1 to 3
  j = 4 - i}
  print(i * j + " ")
println()

7.函式

scala定義函式的標準格式:
def 函式名(引數名1: 引數型別1, 引數名2: 引數型別2) : 返回型別 = {函式體} 
//返回Unit型別的函式
def shout1(content: String) : Unit = {
  	println(content)
}
//返回Unit型別的函式,但是沒有顯式指定返回型別。(當然也可以返回非Unit型別的值)
def shout2(content: String) = {
  println(content)
}
//返回值型別有多種可能,此時也可以省略Unit
def shout3(content: String) = {
  if(content.length >= 3)
    content + "喵喵喵~"
  else
    3
}
//帶有預設值引數的函式,呼叫該函式時,可以只給無預設值的引數傳遞值,也可以都傳遞,新值會覆蓋預設值;傳遞引數時如果不按照定義順序,則可以通過引數名來指定。
def shout4(content: String, leg: Int = 4) = {
  println(content + "," + leg)
}
//遞迴函式在使用時必須有明確的返回值型別
def factorial(n: Int): Int = {
  if(n <= 0)
    1
  else
    n * factorial(n - 1)
}

8.懶值

當val被宣告為懶值的時候,它的初始化會被推辭,只有第一次用到這個變數的時候,才會被呼叫,
object Lazy {
  def init(): String = {
    println("懶值執行了")
  }
  def main(args: Array[String]): Unit = {
    lazy val msg = init()
    println("lazy方法沒有執行")
    println(msg)
  }
}

9.異常

丟擲異常:用throw關鍵字,丟擲一個異常物件。所有異常都是Throwable的子型別。throw表示式是有型別的,就是Nothing,因為Nothing是所有型別的子型別,所以throw表示式可以用在需要型別的地方。 
捕捉異常:在Scala裡,借用了模式匹配的思想來做異常的匹配,因此,在catch的程式碼裡,是一系列case字句。

10.陣列

定長陣列
val arr1 = new Array[Int](10)
arr1(1) = 7
//定義
val arr1 = Array(1, 2)
變長陣列
//定義
val arr2 = ArrayBuffer[Int]()
//追加值
arr2.append(7)
//重新賦值
arr2(0) = 7
定長陣列和變長陣列的相互轉換
arr1.toBuffer
arr2.toArray
多維陣列
//定義
val arr3 = Array.ofDim[Double](3,4)
//賦值
arr3(1)(1) = 11.11
java和scala相互轉換:
val arr4 = ArrayBuffer("1", "2", "3")
//Scala to Java
import scala.collection.JavaConversions.bufferAsJavaList
val javaArr = new ProcessBuilder(arr4)
println(javaArr.command())
// java to scala
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
val scalaArr: Buffer[String] = javaArr.command()
println(scalaArr)
陣列遍歷
for(x <- arr1) {
  println(x)
}

11 元組:

元組可以理解為一個容器,可以存放各種相同或者不同的資料型別

1.元組的建立

val tuple1 = (1, 2, 3, "heiheihei")
println(tuple1)

2.元組的訪問:

val value1 = tuple1._4
println(value1)

3.元組的遍歷

for (elem <- tuple1.productIterator) {
  print(elem)
}
println()

12.列表

//建立列表
val list1 = List(1, 2)
println(list1)
//訪問列表元素
val value1 = list1(1)
println(value1)
//列表追加元素
val list2 = list1 :+ 99
println(list2)
val list3 = 100 +: list1
println(list3)
//List的建立與追加,符號“::”,注意觀察去掉Nil和不去掉Nil的區別,Nil表示為空
val list4 = 1 :: 2 :: 3 :: list1 :: Nil
println(list4)
//

13 對映

1.構造不可變的對映

val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)

2.構造可變對映

val map2 = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)

3.空對映

val map3 = new scala.collection.mutable.HashMap[String, Int]

4.對偶元組

val map4 = Map(("Alice", 10), ("Bob", 20), ("Kotlin", 30))

14 set集合

預設情況下,scala使用的是不可變的集合,如果想用可變集合,則需要引用scala.collection.Set 包

1.set不可變集合的建立

val set = Set(1, 2, 3)
println(set)

2.set可變集合建立,如果import了可變集合,那麼後續使用預設也是可變集合

import scala.collection.mutable.Set
val mutableSet = Set(1, 2, 3)

3.可變集合元素新增

mutableSet.add(4)
mutableSet += 6
// 注意該方法返回一個新的Set集合,而非在原有的基礎上進行新增
mutableSet.+(5)

4.可變集合元素刪除

mutableSet -= 1
mutableSet.remove(2)
println(mutableSet)

5.集合元素與函式的對映

//map::將集合中的每一個元素對映到某一個函式
val names = List("Alice", "Bob", "Nick")
println(names.map(_.toUpperCase))
// flatmap::flat即壓扁,壓平,扁平化,效果就是將集合中的每個元素的子元素對映到某個函式並返回新的集合
val names = List("Alice", "Bob", "Nick")
println(names.flatMap(_.toUpperCase()))

15 摺疊,化簡,掃面

將二元函式引用於集合中的函式
val list = List(1, 2, 3, 4, 5)
val i1 = list.reduceLeft(_ - _)
val i2 = list.reduceRight(_ - _)
println(i1)
println(i2)
1,flod:摺疊
val list2 = List(1, 9, 2, 8)
val i4 = list2.fold(5)((sum, y) => sum + y)
println(i4)

2.統計一句話中,各個文字出現的頻次.

val list2 = List(1, 9, 2, 8)
val i4 = list2.fold(5)((sum, y) => sum + y)
println(i4)