1. 程式人生 > >Scala - 05 - 資料結構

Scala - 05 - 資料結構

1- 陣列(Array)

陣列一般包括定長陣列和變長陣列。 可以不指明陣列型別,Scala會自動根據提供的初始化資料來推斷出陣列的型別。 在Scala中,對陣列元素的應用,是使用圓括號,而不是方括號。 示例:定長陣列 就是長度不變的陣列,在Scala中使用Array進行宣告。
  val myIntArr = new Array[Int](3)                //> myIntArr  : Array[Int] = Array(0, 0, 0)
  myIntArr(0) = 111
  myIntArr(1) = 222
  myIntArr(2) = 333
  for (i <- 0 to 2) println(myIntArr(i))          //> 111
                                                  //| 222
                                                  //| 333

  val myStrArr = new Array[String](3)             //> myStrArr  : Array[String] = Array(null, null, null)
  myStrArr(0) = "AAA"
  myStrArr(1) = "BBB"
  myStrArr(2) = "CCC"
  for (i <- 0 to 2) println(myStrArr(i))          //> AAA
                                                  //| BBB
                                                  //| CCC

  val myIntArr2 = Array(123, 456, 789)            //> myIntArr2  : Array[Int] = Array(123, 456, 789)
  val myStrArr2 = Array("aaa", "bbb", "ccc")      //> myStrArr2  : Array[String] = Array(aaa, bbb, ccc)
注意:陣列元素的初始化值
  • 整型陣列,每個陣列元素初始化為0
  • 字串陣列,每個陣列元素初始化為null

2- 列表(List)

列表是相同型別值的聚集,各個元素必須是相同型別。 列表有頭部和尾部的概念,頭部是一個元素,而尾部則仍然是一個列表。
  • 可以使用intList.head來獲取列表的頭部
  • 可以使用intList.tail來獲取列表的尾部
  • 可以使用“::”操作符,可以在列表的頭部增加新的元素,也可以構建列表
  • 可以使用:::操作符對不同的列表進行連線得到新的列表
Scala列表具備常用的方法。
  val intList = List(1, 2, 3)                     //> intList  : List[Int] = List(1, 2, 3)
  val intList2 = 4 :: 5 :: 6 :: Nil               //> intList2  : List[Int] = List(4, 5, 6)
  val initList3 = 0 :: intList                    //> initList3  : List[Int] = List(0, 1, 2, 3)
  val initList4 = intList ::: intList2            //> initList4  : List[Int] = List(1, 2, 3, 4, 5, 6)
  initList4.sum                                   //> res0: Int = 21

3- 元組(Tuple)

元組是不同型別值的聚集,可以包含不同型別的元素。
  val myTuple = ("AAA", 111, 'v')                 //> myTuple  : (String, Int, Char) = (AAA,111,v)
  println(myTuple._1)                             //> AAA
  println(myTuple._2)                             //> 111
  println(myTuple._3)                             //> v

4- 集(Set)

集是不重複元素的集合,包括可變集和不可變集,都可以進行新增或刪除元素的操作。
  • 對不可變集進行操作,會產生一個新的集,原來的集並不會發生變化。 
  • 對可變集進行操作,改變的是該集本身。
預設情況下建立的是不可變集,通常使用不可變集。 集不會記錄元素的插入順序,而是以“雜湊”方法對元素的值進行組織,可以快速地找到某個元素。
  var mySet = Set("AAA", "BBB")                   //> mySet  : scala.collection.immutable.Set[String] = Set(AAA, BBB)
  mySet += "CCC"
  println(mySet.contains("CCC"))                  //> true
注意:這裡使用var宣告一個可變集合,如果使用val則會報錯。 宣告一個可變集,需要引入scala.collection.mutable.Set包。
package testscala
import scala.collection.mutable.Set

object TestScala {
  def main(args: Array[String]) {
    val myMutableSet = Set("AAA", "BBB")
    myMutableSet += "ccc"
    println(myMutableSet)
  }
}

注意:雖然宣告myMutableSet為val變數,但由於其是可變集,所以能夠可以正確執行myMutableSet += "ccc",不會報錯。

5- 對映(Map)

對映(Map)是一系列鍵值對的集合。在對映中,所有的值都可以通過鍵來獲取。 對映包括可變和不可變兩種,預設情況下建立的是不可變對映。
  • 不可變對映,是無法更新對映中的元素的,也無法增加新的元素。
  • 可變對映,可以更新和新增對映的元素,但在建立時需要引入scala.collection.mutable.Map包。
使用contains方法可以檢查對映中是否包含某個值。
  val test = Map("111" -> "AAA", 222 -> "BBB", "333" -> "CCC")
                                                  //> test  : scala.collection.immutable.Map[Any,String] = Map(111 -> AAA, 222 -> B
                                                  //| BB, 333 -> CCC)
  println(test("111"))                            //> AAA
  println(test(222))                              //> BBB
  if (test.contains("333")) test("333") else 0    //> res0: Any = CCC

示例:可變對映

  import scala.collection.mutable.Map
  val test2 = Map(1 -> "a", 2 -> "b")             //> test2  : scala.collection.mutable.Map[Int,String] = Map(2 -> b, 1 -> a)
  test2(1) = "A"
  test2(3) = "d"
  test2 += (4 -> "d", 5 -> "e")                   //> res0: testrepl.test2.type = Map(2 -> b, 5 -> e, 4 -> d, 1 -> A, 3 -> d)
注意:可以使用+=操作來新增新的元素 示例:迴圈遍歷對映
  • 迴圈遍歷對映的基本格式:for ((k,v) <- 對映) 語句塊
  • 可以同時遍歷k和v,也可以只遍歷對映中的k或者v
  val test3 = Map("1" -> "AAA", "2" -> "BBB", "3" -> "CCC")
                                                  //> test3  : scala.collection.immutable.Map[String,String] = Map(1 -> AAA, 2 -> B
                                                  //| BB, 3 -> CCC)
  for ((k, v) <- test3) printf("Key is : %s and Value is: %s\n", k, v)
                                                  //> Key is : 1 and Value is: AAA
                                                  //| Key is : 2 and Value is: BBB
                                                  //| Key is : 3 and Value is: CCC
  for (k <- test3.keys) println(k)                //> 1
                                                  //| 2
                                                  //| 3
  for (v <- test3.values) println(v)              //> AAA
                                                  //| BBB
                                                  //| CCC
  for (x <- test3) println(x)                     //> (1,AAA)
                                                  //| (2,BBB)
                                                  //| (3,CCC)

6- 迭代器(Iterator)

迭代器不是一個集合,而是提供了訪問集合的一種方法,適用於需要很大開銷操作集合的情況。 迭代器包含兩個基本操作:next和hasNext。
  • next可以返回迭代器的下一個元素
  • hasNext用於檢測是否還有下一個元素
利用這兩個基本操作,可以通過while迴圈或者for迴圈實現對迭代器的遍歷。
  val iter = Iterator("AAA", "BBB", "CCC")        //> iter  : Iterator[String] = non-empty iterator
  while (iter.hasNext) {
    println(iter.next())
  }                                               //> AAA
                                                  //| BBB
                                                  //| CCC
  val iter2 = Iterator("111", "222", "333")       //> iter2  : Iterator[String] = non-empty iterator
  for (elem <- iter2) {
    println(elem)                                 //> 111
                                                  //| 222
                                                  //| 333

7 - 示例

排序示例-1:
  def qSort(x: List[Int]): List[Int] = {
    if (x.length <= 2) x
    else qSort(x.filter(x.head > _)) ++
      x.filter(x.head == _) ++
      qSort(x.filter(x.head < _))
  }                                               //> qSort: (x: List[Int])List[Int]

  qSort(List(6, 4, 5, 3, 1, 2, 9, 8, 0, 7))       //> res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 8, 7, 9)

排序示例-2:

  def qSort(y: List[Int]): List[Int] =
    if (y.length < 2) y
    else qSort(y.filter(_ < y.head)) ++
      y.filter(_ == y.head) ++
      qSort(y.filter(_ > y.head))                 //> qSort: (y: List[Int])List[Int]

  qSort(List(6, 4, 5, 3, 1, 2, 9, 8, 0, 7))       //> res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)