Scala入門系列(十):函數式編程之集合操做

1. Scala的集合體繫結構

Scala中的集合體系主要包括(結構跟Java類似):編程

  • Iterable(全部集合trait的根trait)
  • Seq(Range、ArrayBuffer、List等)
  • Set(HashSet、LinkedHashSet、SortedSet等)
  • Map (HashMap、SortedMap、LinkedHashMap等)

Scala中的集合分爲可變和不可變兩類集合,分別對應scala.collection.mutable和scala.collection.immutable兩個包。app

2. List

List表明一個不可變的列表。編程語言

  • List有head和tail,head表明List的第一個元素,tail表明第一個元素以後的全部元素。
  
scala> val list = List( 1, 2, 3, 4)
list: List[ Int] = List( 1, 2, 3, 4)
scala> list.head
res33: Int = 1
scala> list.tail
res34: List[ Int] = List( 2, 3, 4)

  
案例:用遞歸函數給List中每一個元素都加上指定的前綴並打印函數式編程

  
// 若是List只有一個元素,那麼他的tail就是Nil
def decorator(list: List[ Int], prefix: String){
if (list != Nil) {
println(prefix + list.head)
decorator(list.tail, prefix)
}
}
scala> decorator(list, "+")
+ 1
+ 2
+ 3
+ 4

  • List有特殊的::操做符,能夠用於將head和tail合併成一個List。
  
scala> list
res37: List[ Int] = List( 1, 2, 3, 4)
scala> 0::list
res38: List[ Int] = List( 0, 1, 2, 3, 4)

該操做符在Spark源碼中有體現函數

3. LinkedList

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 = list
var first = true
while( currentList != Nil && currentList.next != Nil){
if(first) { currentList.elem *= 2; first = false}
currentList = currentList.next.next
if(currentList != Nil) currentList.elem *= 2
}
list: scala.collection.mutable. LinkedList[ Int] = LinkedList( 2, 2, 6, 4, 10, 6, 14, 8, 18)

4. Set

Set表明一個沒有重複元素的集合scala

HashSet

不保證插入順序,元素是亂序的code

  
scala> val s = new scala.collection.mutable. HashSet[ Int]()
s: scala.collection.mutable. HashSet[ Int] = Set()
scala> s += 1
res40: s. type = Set( 1)
scala> s += 2
res41: s. type = Set( 1, 2)
scala> s += 5
res42: s. type = Set( 1, 5, 2)

LinkedHashSet

保證插入順序,底層使用鏈表對象

  
scala> val s = new scala.collection.mutable. LinkedHashSet[ Int]()
s: scala.collection.mutable. LinkedHashSet[ Int] = Set()
scala> s += 1
res43: s. type = Set( 1)
scala> s += 2
res44: s. type = Set( 1, 2)
scala> s += 5
res45: s. type = Set( 1, 2, 5)

SortedSet

會自動根據key來進行排序(默認字母順序)

  
scala> val s = scala.collection.mutable. SortedSet( "orange", "apple", "banana")
s: scala.collection.mutable. SortedSet[ String] = TreeSet(apple, banana, orange)

5. 集合的函數式編程(重要!)

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 world
your are my friend
// 學生姓名和成績進行關聯
scala> List( "leo", "jen", "jack").zip( List( 100, 30, 20))
res50: List[( String, Int)] = List((leo, 100), (jen, 30), (jack, 20))

6. 綜合案例:統計多個文本內的單詞總數

  
// 使用scala的IO包將文件文件內的數據讀取出來
scala> val lines1 = scala.io. Source.fromFile( "E://test.txt").mkString
lines1: String = hello my
scala> val lines2 = scala.io. Source.fromFile( "E://test2.txt").mkString
lines2: String = you are a good boy
// 使用List的伴生對象,將多個文件內的內容建立爲一個List
scala> 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的函數式編程。

相關文章
相關標籤/搜索