Scala數據結構(二)

一、集合的基礎操作

1,head頭信息

//獲取集合的第一個元素
val list = List(1,3,5) 
list.head    //1

2,tail尾信息

//獲取集合除去頭元素之外的所有元素
val list = List(1,3,5)
list.tail //List(3,5)

3,last最後元素

//獲取集合的最後一個元素
val list = List(1,3,5)
list.last    //5

4,init初始化

//獲取集合除去最後一個元素的前面所有元素
val list = List(1,3,5)
println(list.init)    //List(1,3)

5,reverse反轉

//集合反轉
val list = List(1,3,5)
val resList: List[Int] = list.reverse    //List(5, 3, 1)

6,sum、max、min

val list = List(1,3,5)
println(list.sum)    //9 求和
println(list.max)    //5 最大值        
println(list.min)    //1 最小值

7,take(n)獲取前n個元素

val list = List(1,3,5)
val takeList = list.take(1)    //List(1)

 

二、集合的高級操作

1,sortBy和sortWith

//sortBy只能按照升序排列,sortWith可自定義升降序
val list = List(10,9,1,4,7,3)
val sortByList: List[Int] = list.sortBy(x=>x)   //List(1, 3, 4, 7, 9, 10) 
val sortWithList: List[Int] = list.sortWith((left,right)=>left>right)    //List(10, 9, 7, 4, 3, 1),如果要升序可以left<right

2,groupBy分組

//定義按照元素分組會生成對應的map
val list = List(3,9,1,4,1,3)
val groupByMap: Map[Int, List[Int]] = list.groupBy(x=>x)    //Map(4 -> List(4), 1 -> List(1, 1), 9 -> List(9), 3 -> List(3, 3))

3,map映射

  在Scala中可以通過map映射操作來解決:將集合中的每一個元素通過指定功能(函數)映射(轉換)成新的結果集合。這裏其實就是所謂的將函數作爲參數傳遞給另外一個函數,這是函數式編程的特點

//將list集合中的每個元素*2
val list = List(1,3,5)
val newList: List[Int] = list.map(_*2) //List(2,6,10)

4,flatMap扁平化

  將集合中的每個元素的子元素映射到某個函數並返回新的集合。

val list = List(List(1,2,3),1,List(4,98))
val newList = list.flatMap {
  case item =>
    //判斷類型如果是List[Any]類型就轉換
    if (item.isInstanceOf[List[Any]]) {
      item.asInstanceOf[List[Any]]
    } else {
      //如果是普通類型就直接List(item)包裝
      List(item)
    }
}
println(newList)    //List(1, 2, 3, 1, 4, 98)

5,filter過濾

//filter過濾獲取爲true的元素組成集合
val list = List(1, 25, 3, 11, 4, 98)
val filterList: List[Int] = list.filter(_ > 20)    //List(25, 98)

6,reduce化簡

      

val list = List(1, 2, 3, 4)
//1+2+3+4       10
val reduceLeft: Int = list.reduce(_ + _)
//1-(2-(3-4))   -2
val reduceRight: Int = list.reduceRight(_ - _)

7,folder摺疊

   

val list = List(1, 2, 3, 4) //集合List
//(100,1, 2, 3, 4) =>化簡  (((100-1)-2) -3)) – 4 = 90
println(list.foldLeft(100)(_-_)) // [函數柯里化(將多個參數,分別傳遞)]
//(1,2,3,4,100) => 化簡 1-(2-(3-(4-100))) = 98
println(list.foldRight(100)(_-_))

 

三、模式匹配

  模式匹配語法中,採用match關鍵字聲明,每個分支採用case關鍵字進行聲明,當需要匹配時,會從第一個case分支開始,如果匹配成功,那麼執行對應的邏輯代碼,如果匹配不成功,繼續執行下一個分支進行判斷。如果所有case都不匹配,那麼會執行case _ 分支,類似於Javadefault語句

1,類型匹配

val oper = '-'
val n1 = 20
val n2 = 10
var res = 0
oper match {
  case '+' => res = n1 + n2
  case '-' => res = n1 - n2
  case '*' => res = n1 * n2case '/' => res = n1 / n2
  case _ => println("oper error")
}
println("res=" + res) //10
1)如果所有case都不匹配,那麼會執行case _ 分支,類似於Java中default語句
2)如果所有case都不匹配,又沒有寫case _ 分支,那麼會拋出MatchError
3)每個case中,不用break語句,自動中斷case
4)可以在match中使用其它類型,而不僅僅是字符,可以是表達式
5)=> 等價於 java swtich 的 :
6)=> 後面的代碼塊到下一個 case, 是作爲一個整體執行,可以使用{} 擴起來,也可以不擴。 

2,匹配列表

for (list <- Array(List(0), List(1, 0), List(88), List(0, 0, 0), List(1, 0, 0))) {
  val result = list match {
    case 0 :: Nil => "0" // 匹配的 List(0)
    case x :: y :: Nil => x + " " + y // 匹配的是有兩個元素的List(x,y)
    case 0 :: tail => "0 ..." // 匹配 以0 開頭的後面有任意元素的List
    case x :: Nil => List(x)
    case _ => "something else"
  }
  println(result)
}

3,匹配元組

//請返回 (34, 89) => (89,34)
for (pair <- Array((0, 1),(34,89), (1, 0), (1, 1),(1,0,2))) {
  val result = pair match { //
    case (0, _) => "0 ..." // 表示匹配 0 開頭的二元組
    case (y, 0) => y //表示匹配 0 結尾的二元組
    case (x,y) => (y,x)
    case _ => "other" //.默認
  }
  println(result)
}

4,對象匹配

val number: Double = 36.0 //Square(6.0)
number match {
  case Square(n) => println(n) // 6.0
  case _ => println("nothing matched")
}

//說明
//1. unapply 爲對象提取器
//2. apply 對象構建器
object Square { //靜態性質
  def unapply(z: Double): Option[Double] = {
    println("unapply 被調用 z =" + z) // 36.0
    Some(math.sqrt(z)) // Some(6.0)
  }
  def apply(z: Double): Double = z * z
}
1)構建對象時apply會被調用 ,比如 val n1 = Square(5)
2)當將 Square(n) 寫在 case 後時[case Square(n) => xxx],會默認調用unapply 方法(對象提取器)
3)number 會被 傳遞給def unapply(z: Double) 的 z 形參
4)如果返回的是Some集合,則unapply提取器返回的結果會返回給 n 這個形參
5)case中對象的unapply方法(提取器)返回some集合則爲匹配成功
6)返回None集合則爲匹配失敗

4,for循環

val map = Map("A"->1, "B"->0, "C"->3) //map集合
for ( (k, v) <- map ) { //每次遍歷,取出k和v
  println(k + " -> " + v)
}
//說明: 只會取出 value= 0 的 k-v
println("==================================")
for ((k, 0) <- map) {
  println(k + " --> " + 0)
}
println("=====================================")
//說明 取出 value 在 [0,3] 的範圍的 key-val
for ((k, v) <- map if v > 0 && v < 3) {
  println(k + " ---> " + v)
}

5,樣例類

1)樣例類仍然是類
2)樣例類用case關鍵字進行聲明。
3)樣例類是爲模式匹配(對象)而優化的類
4)構造器中的每一個參數都成爲val——除非它被顯式地聲明爲var(不建議這樣做)
5)在樣例類對應的伴生對象中提供apply方法讓你不用new關鍵字就能構造出相應的對象
6)提供unapply方法讓模式匹配可以工作
7)將自動生成toString、equals、hashCode和copy方法(有點類似模板類,直接給生成,供程序員使用)

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章