List 是 Scala 中很是重要的一個數據結構,其與 Array(數組) 很是相似,可是 List 是不可變的,和 Java 中的 List 同樣,其底層實現是鏈表。java
scala> val list = List("hadoop", "spark", "storm") list: List[String] = List(hadoop, spark, storm) // List 是不可變 scala> list(1) = "hive" <console>:9: error: value update is not a member of List[String]
Scala 中 List 具備如下兩個特性:git
List[S]
就是 List[T]
的子類型,例如 List[String]
是 List[Object]
的子類型。須要特別說明的是空列表的類型爲 List[Nothing]
:es6
scala> List() res1: List[Nothing] = List()
全部 List 都由兩個基本單元構成:Nil
和 ::
(讀做"cons")。即列表要麼是空列表 (Nil),要麼是由一個 head 加上一個 tail 組成,而 tail 又是一個 List。咱們在上面使用的 List("hadoop", "spark", "storm")
最終也是被解釋爲 "hadoop"::"spark":: "storm"::Nil
。github
scala> val list01 = "hadoop"::"spark":: "storm"::Nil list01: List[String] = List(hadoop, spark, storm) // :: 操做符號是右結合的,因此上面的表達式和下面的等同 scala> val list02 = "hadoop"::("spark":: ("storm"::Nil)) list02: List[String] = List(hadoop, spark, storm)
Scala 支持展開列表以實現模式匹配。編程
scala> val list = List("hadoop", "spark", "storm") list: List[String] = List(hadoop, spark, storm) scala> val List(a,b,c)=list a: String = hadoop b: String = spark c: String = storm
若是隻須要匹配部份內容,能夠以下:數組
scala> val a::rest=list a: String = hadoop rest: List[String] = List(spark, storm)
object ScalaApp extends App { val list = List("hadoop", "spark", "storm") // 1.列表是否爲空 list.isEmpty // 2.返回列表中的第一個元素 list.head // 3.返回列表中除第一個元素外的全部元素 這裏輸出 List(spark, storm) list.tail // 4.tail 和 head 能夠結合使用 list.tail.head // 5.返回列表中的最後一個元素 與 head 相反 list.init // 6.返回列表中除了最後一個元素以外的其餘元素 與 tail 相反 這裏輸出 List(hadoop, spark) list.last // 7.使用下標訪問元素 list(2) // 8.獲取列表長度 list.length // 9. 反轉列表 list.reverse }
indices 方法返回全部下標。數據結構
scala> list.indices res2: scala.collection.immutable.Range = Range(0, 1, 2)
scala> list take 2 res3: List[String] = List(hadoop, spark) scala> list drop 2 res4: List[String] = List(storm) scala> list splitAt 2 res5: (List[String], List[String]) = (List(hadoop, spark),List(storm))
flatten 接收一個由列表組成的列表,並將其進行扁平化操做,返回單個列表。函數式編程
scala> List(List(1, 2), List(3), List(), List(4, 5)).flatten res6: List[Int] = List(1, 2, 3, 4, 5)
對兩個 List 執行 zip
操做結果以下,返回對應位置元素組成的元組的列表,unzip
則執行反向操做。函數
scala> val list = List("hadoop", "spark", "storm") scala> val score = List(10,20,30) scala> val zipped=list zip score zipped: List[(String, Int)] = List((hadoop,10), (spark,20), (storm,30)) scala> zipped.unzip res7: (List[String], List[Int]) = (List(hadoop, spark, storm),List(10, 20, 30))
toString 返回 List 的字符串表現形式。oop
scala> list.toString res8: String = List(hadoop, spark, storm)
若是想改變 List 的字符串表現形式,能夠使用 mkString。mkString 有三個重載方法,方法定義以下:
// start:前綴 sep:分隔符 end:後綴 def mkString(start: String, sep: String, end: String): String = addString(new StringBuilder(), start, sep, end).toString // seq 分隔符 def mkString(sep: String): String = mkString("", sep, "") // 若是不指定分隔符 默認使用""分隔 def mkString: String = mkString("")
使用示例以下:
scala> list.mkString res9: String = hadoopsparkstorm scala> list.mkString(",") res10: String = hadoop,spark,storm scala> list.mkString("{",",","}") res11: String = {hadoop,spark,storm}
iterator 方法返回的是迭代器,這和其餘語言的使用是同樣的。
object ScalaApp extends App { val list = List("hadoop", "spark", "storm") val iterator: Iterator[String] = list.iterator while (iterator.hasNext) { println(iterator.next) } }
toArray 和 toList 用於 List 和數組之間的互相轉換。
scala> val array = list.toArray array: Array[String] = Array(hadoop, spark, storm) scala> array.toList res13: List[String] = List(hadoop, spark, storm)
copyToArray 將 List 中的元素拷貝到數組中指定位置。
object ScalaApp extends App { val list = List("hadoop", "spark", "storm") val array = Array("10", "20", "30") list.copyToArray(array,1) println(array.toBuffer) } // 輸出 :ArrayBuffer(10, hadoop, spark)
map 與 Java 8 函數式編程中的 map 相似,都是對 List 中每個元素執行指定操做。
scala> List(1,2,3).map(_+10) res15: List[Int] = List(11, 12, 13)
flatMap 與 map 相似,但若是 List 中的元素仍是 List,則會對其進行 flatten 操做。
scala> list.map(_.toList) res16: List[List[Char]] = List(List(h, a, d, o, o, p), List(s, p, a, r, k), List(s, t, o, r, m)) scala> list.flatMap(_.toList) res17: List[Char] = List(h, a, d, o, o, p, s, p, a, r, k, s, t, o, r, m)
foreach 要求右側的操做是一個返回值爲 Unit 的函數,你也能夠簡單理解爲執行一段沒有返回值代碼。
scala> var sum = 0 sum: Int = 0 scala> List(1, 2, 3, 4, 5) foreach (sum += _) scala> sum res19: Int = 15
filter 用於篩選知足條件元素,返回新的 List。
scala> List(1, 2, 3, 4, 5) filter (_ % 2 == 0) res20: List[Int] = List(2, 4)
partition 會按照篩選條件對元素進行分組,返回類型是 tuple(元組)。
scala> List(1, 2, 3, 4, 5) partition (_ % 2 == 0) res21: (List[Int], List[Int]) = (List(2, 4),List(1, 3, 5))
find 查找第一個知足條件的值,因爲可能並不存在這樣的值,因此返回類型是 Option
,能夠經過 getOrElse
在不存在知足條件值的狀況下返回默認值。
scala> List(1, 2, 3, 4, 5) find (_ % 2 == 0) res22: Option[Int] = Some(2) val result: Option[Int] = List(1, 2, 3, 4, 5) find (_ % 2 == 0) result.getOrElse(10)
takeWhile 遍歷元素,直到遇到第一個不符合條件的值則結束遍歷,返回全部遍歷到的值。
scala> List(1, 2, 3, -4, 5) takeWhile (_ > 0) res23: List[Int] = List(1, 2, 3)
dropWhile 遍歷元素,直到遇到第一個不符合條件的值則結束遍歷,返回全部未遍歷到的值。
// 第一個值就不知足條件,因此返回列表中全部的值 scala> List(1, 2, 3, -4, 5) dropWhile (_ < 0) res24: List[Int] = List(1, 2, 3, -4, 5) scala> List(1, 2, 3, -4, 5) dropWhile (_ < 3) res26: List[Int] = List(3, -4, 5)
span 遍歷元素,直到遇到第一個不符合條件的值則結束遍歷,將遍歷到的值和未遍歷到的值分別放入兩個 List 中返回,返回類型是 tuple(元組)。
scala> List(1, 2, 3, -4, 5) span (_ > 0) res27: (List[Int], List[Int]) = (List(1, 2, 3),List(-4, 5))
forall 檢查 List 中全部元素,若是全部元素都知足條件,則返回 true。
scala> List(1, 2, 3, -4, 5) forall ( _ > 0 ) res28: Boolean = false
exists 檢查 List 中的元素,若是某個元素已經知足條件,則返回 true。
scala> List(1, 2, 3, -4, 5) exists (_ > 0 ) res29: Boolean = true
sortWith 對 List 中全部元素按照指定規則進行排序,因爲 List 是不可變的,因此排序返回一個新的 List。
scala> List(1, -3, 4, 2, 6) sortWith (_ < _) res30: List[Int] = List(-3, 1, 2, 4, 6) scala> val list = List( "hive","spark","azkaban","hadoop") list: List[String] = List(hive, spark, azkaban, hadoop) scala> list.sortWith(_.length>_.length) res33: List[String] = List(azkaban, hadoop, spark, hive)
上面介紹的全部方法都是 List 類上的方法,下面介紹的是 List 伴生對象中的方法。
List.range 能夠產生指定的前閉後開區間內的值組成的 List,它有三個可選參數: start(開始值),end(結束值,不包含),step(步長)。
scala> List.range(1, 5) res34: List[Int] = List(1, 2, 3, 4) scala> List.range(1, 9, 2) res35: List[Int] = List(1, 3, 5, 7) scala> List.range(9, 1, -3) res36: List[Int] = List(9, 6, 3)
List.fill 使用指定值填充 List。
scala> List.fill(3)("hello") res37: List[String] = List(hello, hello, hello) scala> List.fill(2,3)("world") res38: List[List[String]] = List(List(world, world, world), List(world, world, world))
List.concat 用於拼接多個 List。
scala> List.concat(List('a', 'b'), List('c')) res39: List[Char] = List(a, b, c) scala> List.concat(List(), List('b'), List('c')) res40: List[Char] = List(b, c) scala> List.concat() res41: List[Nothing] = List()
當多個 List 被放入同一個 tuple 中時候,能夠經過 zipped 對多個 List 進行關聯處理。
// 兩個 List 對應位置的元素相乘 scala> (List(10, 20), List(3, 4, 5)).zipped.map(_ * _) res42: List[Int] = List(30, 80) // 三個 List 的操做也是同樣的 scala> (List(10, 20), List(3, 4, 5), List(100, 200)).zipped.map(_ * _ + _) res43: List[Int] = List(130, 280) // 判斷第一個 List 中元素的長度與第二個 List 中元素的值是否相等 scala> (List("abc", "de"), List(3, 2)).zipped.forall(_.length == _) res44: Boolean = true
上面介紹的 List,因爲其底層實現是鏈表,這意味着能快速訪問 List 頭部元素,但對尾部元素的訪問則比較低效,這時候能夠採用 ListBuffer
,ListBuffer 提供了在常量時間內往頭部和尾部追加元素。
import scala.collection.mutable.ListBuffer object ScalaApp extends App { val buffer = new ListBuffer[Int] // 1.在尾部追加元素 buffer += 1 buffer += 2 // 2.在頭部追加元素 3 +=: buffer // 3. ListBuffer 轉 List val list: List[Int] = buffer.toList println(list) } //輸出:List(3, 1, 2)
Set 是不重複元素的集合。分爲可變 Set 和不可變 Set。
object ScalaApp extends App { // 可變 Set val mutableSet = new collection.mutable.HashSet[Int] // 1.添加元素 mutableSet.add(1) mutableSet.add(2) mutableSet.add(3) mutableSet.add(3) mutableSet.add(4) // 2.移除元素 mutableSet.remove(2) // 3.調用 mkString 方法 輸出 1,3,4 println(mutableSet.mkString(",")) // 4. 獲取 Set 中最小元素 println(mutableSet.min) // 5. 獲取 Set 中最大元素 println(mutableSet.max) }
不可變 Set 沒有 add 方法,能夠使用 +
添加元素,可是此時會返回一個新的不可變 Set,原來的 Set 不變。
object ScalaApp extends App { // 不可變 Set val immutableSet = new collection.immutable.HashSet[Int] val ints: HashSet[Int] = immutableSet+1 println(ints) } // 輸出 Set(1)
多個 Set 之間能夠進行求交集或者合集等操做。
object ScalaApp extends App { // 聲明有序 Set val mutableSet = collection.mutable.SortedSet(1, 2, 3, 4, 5) val immutableSet = collection.immutable.SortedSet(3, 4, 5, 6, 7) // 兩個 Set 的合集 輸出:TreeSet(1, 2, 3, 4, 5, 6, 7) println(mutableSet ++ immutableSet) // 兩個 Set 的交集 輸出:TreeSet(3, 4, 5) println(mutableSet intersect immutableSet) }
更多大數據系列文章能夠參見 GitHub 開源項目: 大數據入門指南