Scala中常見的容器 List

爲何選擇Scala?

Scala是一門混合了函數式和麪向對象的語言。用Scala創建多線程應用時,你會傾向於函數式編程風格,用不變狀態編寫無鎖代碼。Scala提供一個基於actor的消息傳遞模型,消除了涉及併發的痛苦問題。運用這個模型, 你可以寫出簡潔的多線程代碼,而無需顧慮多線程間的數據競爭,以及處理加鎖和釋放帶來的痛苦。下面介紹一下在Scala中常見的容器. List


List

Set和Map都有可變和不可變的實現,List與他們不同,只有不變實現。通過使用head方法,Scala將訪問List的第一個元素變得更容易更快捷。除了第一個元素之外所有元素都可以用tail方法訪問。訪問List的最後一個元素需要便利List,所以 同訪問head和tail相比,這個操作的代價會更大。

Scala中列表是非常類似於數組,這意味着,一個列表的所有元素都具有相同的類型,但有兩個重要的區別。首先,列表是不可變的,這意味着一個列表的元素可以不被分配來改變。第二,列表表示一個鏈表,而數組平坦的。

具有T類型的元素的列表的類型被寫爲List[T]。例如,這裏有各種數據類型定義的一些列表:

// List of Strings
val fruit: List[String] = List("apples", "oranges", "pears")

// List of Integers
val nums: List[Int] = List(1, 2, 3, 4)

// Empty List.
val empty: List[Nothing] = List()

// Two dimensional list
val dim: List[List[Int]] =
   List(
      List(1, 0, 0),
      List(0, 1, 0),
      List(0, 0, 1)
   )
所有的列表可以使用兩種基本的構建模塊來定義,一個無尾Nil和::,這有明顯的缺點。Nil也代表了空列表。所有上述列表可以定義如下:

// List of Strings
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))

// List of Integers
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))

// Empty List.
val empty = Nil

// Two dimensional list
val dim = (1 :: (0 :: (0 :: Nil))) ::
          (0 :: (1 :: (0 :: Nil))) ::
          (0 :: (0 :: (1 :: Nil))) :: Nil

列表的基本操作:



上列出了所有的操作都可以體現在以下三個方法來講:

head 此方法返回的列表中的第一個元素。
tail 此方法返回一個由除了第一個元素外的所有元素的列表。
isEmpty 如果列表爲空,此方法返回true,否則爲false。
以下是上述方法中的例子顯示用法:

object Test {
   def main(args: Array[String]) {
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      val nums = Nil

      println( "Head of fruit : " + fruit.head )
      println( "Tail of fruit : " + fruit.tail )
      println( "Check if fruit is empty : " + fruit.isEmpty )
      println( "Check if nums is empty : " + nums.isEmpty )
   }
}
當上述代碼被編譯和執行時,它產生了以下結果:

C:/>scalac Test.scala
C:/>scala Test
Head of fruit : apples
Tail of fruit : List(oranges, pears)
Check if fruit is empty : false
Check if nums is empty : true

C:/>

串聯列表:




可以使用:::運算符或列表List.:::()方法或List.concat()方法來添加兩個或多個列表。下面是一個例子:

object Test {
   def main(args: Array[String]) {
      val fruit1 = "apples" :: ("oranges" :: ("pears" :: Nil))
      val fruit2 = "mangoes" :: ("banana" :: Nil)

      // use two or more lists with ::: operator
      var fruit = fruit1 ::: fruit2
      println( "fruit1 ::: fruit2 : " + fruit )
      
      // use two lists with Set.:::() method
      fruit = fruit1.:::(fruit2)
      println( "fruit1.:::(fruit2) : " + fruit )

      // pass two or more lists as arguments
      fruit = List.concat(fruit1, fruit2)
      println( "List.concat(fruit1, fruit2) : " + fruit  )
      

   }
}
讓我們編譯和運行上面的程序,這將產生以下結果:

C:/>scalac Test.scala
C:/>scala Test
fruit1 ::: fruit2 : List(apples, oranges, pears, mangoes, banana)
fruit1.:::(fruit2) : List(mangoes, banana, apples, oranges, pears)
List.concat(fruit1, fruit2) : List(apples, oranges, pears, mangoes, banana)

C:/>

創建統一列表:

可以使用List.fill()方法創建,包括相同的元素如下的零個或更多個拷貝的列表:

object Test {
   def main(args: Array[String]) {
      val fruit = List.fill(3)("apples") // Repeats apples three times.
      println( "fruit : " + fruit  )

      val num = List.fill(10)(2)         // Repeats 2, 10 times.
      println( "num : " + num  )
   }
}
讓我們編譯和運行上面的程序,這將產生以下結果:

C:/>scalac Test.scala
C:/>scala Test
fruit : List(apples, apples, apples)
num : List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)

C:/>

製成表格一個功能:

可以使用一個函數連同List.tabulate()方法制表列表之前的列表中的所有元素以應用。它的參數是一樣List.fill:第一個參數列表給出的列表的尺寸大小,而第二描述列表的元素。唯一的區別在於,代替的元素被固定,它們是從一個函數計算:

object Test {
   def main(args: Array[String]) {
      // Creates 5 elements using the given function.
      val squares = List.tabulate(6)(n => n * n)
      println( "squares : " + squares  )

      // 
      val mul = List.tabulate( 4,5 )( _ * _ )      
      println( "mul : " + mul  )
   }
}
讓我們編譯和運行上面的程序,這將產生以下結果:

C:/>scalac Test.scala
C:/>scala Test
squares : List(0, 1, 4, 9, 16, 25)
mul : List(List(0, 0, 0, 0, 0), List(0, 1, 2, 3, 4), 
           List(0, 2, 4, 6, 8), List(0, 3, 6, 9, 12))

C:/>

反向列表順序:

可以使用List.reverse方法來扭轉列表中的所有元素。以下爲例子來說明的用法:

object Test {
   def main(args: Array[String]) {
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      println( "Before reverse fruit : " + fruit )

      println( "After reverse fruit : " + fruit.reverse )
   }
}
讓我們編譯和運行上面的程序,這將產生以下結果:

C:/>scalac Test.scala
C:/>scala Test
Before reverse fruit : List(apples, oranges, pears)
After reverse fruit : List(pears, oranges, apples)

C:/>

Scala列表方法:

以下是重要的方法,可以在使用列表時。有關可用方法的完整列表,請Scala的官方文件。

SN 方法及描述
1 def +(elem: A): List[A]
前置一個元素列表
2 def ::(x: A): List[A]
在這個列表的開頭添加的元素。
3 def :::(prefix: List[A]): List[A]
增加了一個給定列表中該列表前面的元素。
4 def ::(x: A): List[A]
增加了一個元素x在列表的開頭
5 def addString(b: StringBuilder): StringBuilder
追加列表的一個字符串生成器的所有元素。
6 def addString(b: StringBuilder, sep: String): StringBuilder
追加列表的使用分隔字符串一個字符串生成器的所有元素。
7 def apply(n: Int): A
選擇通過其在列表中索引的元素
8 def contains(elem: Any): Boolean
測試該列表中是否包含一個給定值作爲元素。
9 def copyToArray(xs: Array[A], start: Int, len: Int): Unit
列表的副本元件陣列。填充給定的數組xs與此列表中最多len個元素,在位置開始。
10 def distinct: List[A]
建立從列表中沒有任何重複的元素的新列表。
11 def drop(n: Int): List[A]
返回除了第n個的所有元素。
12 def dropRight(n: Int): List[A]
返回除了最後的n個的元素
13 def dropWhile(p: (A) => Boolean): List[A]
丟棄滿足謂詞的元素最長前綴。
14 def endsWith[B](that: Seq[B]): Boolean
測試列表是否使用給定序列結束。
15 def equals(that: Any): Boolean
equals方法的任意序列。比較該序列到某些其他對象。
16 def exists(p: (A) => Boolean): Boolean
測試謂詞是否持有一些列表的元素。
17 def filter(p: (A) => Boolean): List[A]
返回列表滿足謂詞的所有元素。
18 def forall(p: (A) => Boolean): Boolean
測試謂詞是否持有該列表中的所有元素。
19 def foreach(f: (A) => Unit): Unit
應用一個函數f以列表的所有元素。
20 def head: A
選擇列表的第一個元素
21 def indexOf(elem: A, from: Int): Int
經過或在某些起始索引查找列表中的一些值第一次出現的索引。
22 def init: List[A]
返回除了最後的所有元素
23 def intersect(that: Seq[A]): List[A]
計算列表和另一序列之間的多重集交集。
24 def isEmpty: Boolean
測試列表是否爲空
25 def iterator: Iterator[A]
創建一個新的迭代器中包含的可迭代對象中的所有元素
26 def last: A
返回最後一個元素
27 def lastIndexOf(elem: A, end: Int): Int
之前或在一個給定的最終指數查找的列表中的一些值最後一次出現的索引
28 def length: Int
返回列表的長度
29 def map[B](f: (A) => B): List[B]
通過應用函數以g這個列表中的所有元素構建一個新的集合
30 def max: A
查找最大的元素
31 def min: A
查找最小元素
32 def mkString: String
顯示列表的字符串中的所有元素
33 def mkString(sep: String): String
顯示的列表中的字符串中使用分隔串的所有元素
34 def reverse: List[A]
返回新列表,在相反的順序元素
35 def sorted[B >: A]: List[A]
根據排序對列表進行排序
36 def startsWith[B](that: Seq[B], offset: Int): Boolean
測試該列表中是否包含給定的索引處的給定的序列
37 def sum: A
概括這個集合的元素
38 def tail: List[A]
返回除了第一的所有元素
39 def take(n: Int): List[A]
返回前n個元素
40 def takeRight(n: Int): List[A]
返回最後n個元素
41 def toArray: Array[A]
列表以一個數組變換
42 def toBuffer[B >: A]: Buffer[B]
列表以一個可變緩衝器轉換
43 def toMap[T, U]: Map[T, U]
此列表的映射轉換
44 def toSeq: Seq[A]
列表的序列轉換
45 def toSet[B >: A]: Set[B]
列表到集合變換
46 def toString(): String
列表轉換爲字符串



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