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