Scala中的集合體系主要包括(結構跟Java類似):編程
Scala中的集合分爲可變和不可變兩類集合,分別對應scala.collection.mutable和scala.collection.immutable兩個包。app
List表明一個不可變的列表。編程語言
scala> val list = List( 1, 2, 3, 4)list: List[ Int] = List( 1, 2, 3, 4)scala> list.headres33: Int = 1scala> list.tailres34: List[ Int] = List( 2, 3, 4)
案例:用遞歸函數給List中每一個元素都加上指定的前綴並打印函數式編程
// 若是List只有一個元素,那麼他的tail就是Nildef decorator(list: List[ Int], prefix: String){if (list != Nil) {println(prefix + list.head)decorator(list.tail, prefix)}}scala> decorator(list, "+")+ 1+ 2+ 3+ 4
::
操做符,能夠用於將head和tail合併成一個List。scala> listres37: List[ Int] = List( 1, 2, 3, 4)scala> 0::listres38: List[ Int] = List( 0, 1, 2, 3, 4)
該操做符在Spark源碼中有體現函數
LinkedList表明一個可變的列表,其elem和next屬性相似於List的head和tail。es5
案例:使用while循環將LinkedList中每一個一個元素乘以二。spa
val list = scala.collection.mutable. LinkedList( 1, 2, 3, 4, 5, 6, 7, 8, 9)var currentList = listvar first = truewhile( currentList != Nil && currentList.next != Nil){if(first) { currentList.elem *= 2; first = false}currentList = currentList.next.nextif(currentList != Nil) currentList.elem *= 2}list: scala.collection.mutable. LinkedList[ Int] = LinkedList( 2, 2, 6, 4, 10, 6, 14, 8, 18)
Set表明一個沒有重複元素的集合scala
不保證插入順序,元素是亂序的code
scala> val s = new scala.collection.mutable. HashSet[ Int]()s: scala.collection.mutable. HashSet[ Int] = Set()scala> s += 1res40: s. type = Set( 1)scala> s += 2res41: s. type = Set( 1, 2)scala> s += 5res42: s. type = Set( 1, 5, 2)
保證插入順序,底層使用鏈表對象
scala> val s = new scala.collection.mutable. LinkedHashSet[ Int]()s: scala.collection.mutable. LinkedHashSet[ Int] = Set()scala> s += 1res43: s. type = Set( 1)scala> s += 2res44: s. type = Set( 1, 2)scala> s += 5res45: s. type = Set( 1, 2, 5)
會自動根據key來進行排序(默認字母順序)
scala> val s = scala.collection.mutable. SortedSet( "orange", "apple", "banana")s: scala.collection.mutable. SortedSet[ String] = TreeSet(apple, banana, orange)
Scala中集合的函數式編程最大的體現就是對於一系列高階函數的使用。
高階函數的使用是Scala與Java最大的區別!由於Java中沒有函數式編程,也確定沒有高階函數,沒法直接將函數傳入一個方法,或者讓一個方法返回一個函數。
// 爲List中的每一個元素都添加一個前綴scala> List( "leo", "spark", "peter").map( "name is " + _)res47: List[ String] = List(name is leo, name is spark, name is peter)// 拆分單詞scala> List( "Hello world", "your are my friend").flatMap(_.split( " "))res48: List[ String] = List( Hello, world, your, are, my, friend)// 打印每個元素scala> List( "Hello world", "your are my friend").foreach(println(_))Hello worldyour are my friend// 學生姓名和成績進行關聯scala> List( "leo", "jen", "jack").zip( List( 100, 30, 20))res50: List[( String, Int)] = List((leo, 100), (jen, 30), (jack, 20))
// 使用scala的IO包將文件文件內的數據讀取出來scala> val lines1 = scala.io. Source.fromFile( "E://test.txt").mkStringlines1: String = hello myscala> val lines2 = scala.io. Source.fromFile( "E://test2.txt").mkStringlines2: String = you are a good boy// 使用List的伴生對象,將多個文件內的內容建立爲一個Listscala> val lines = List(lines1, lines2)lines: List[ String] = List(hello my, you are a good boy)// 首先將全部元素以空格分割單詞,接着將每一個單詞映射爲(單詞,1)元組, 而後再取出元組裏的第二個元素(_._2表示取出元組中的第二個元素),最後作累加scala> lines.flatMap(_.split( " ")).map((_, 1)).map(_._2).reduceLeft(_ + _)res51: Int = 7
注意:最後一行多個高階函數的鏈式調用其實就是Scala函數式編程的精髓所在,也是Scala相較於Java等編程語言最大的功能優點所在。而且Spark的源碼中大量使用了這種複雜的鏈式調用,Spark自己提供的開發API也徹底沿用了Scala的函數式編程。