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的函数式编程。

相关文章
相关标签/搜索