Scala的集合体系结构
Scala 中的集合体系主要包括:Iterable、Seq、Set、Map。
其中 Iterable 是所有集合 trait 的根 trait。这个结构与Java的集合体系非常相似。
Scala 中的集合是分成可变和不可变两类集合的,其中可变集合就是说,集合的元素可以动态修改,而不可变集合的元素在初始化之后,就无法修改了。分别对应 scala.collection.mutable 和 scala.collection.immutable 两个包。
Seq 下包含了 Range、ArrayBuffer、List 等子 trait。其中Range 就代表了一个序列,通常可以使用 “1 to 10” 这种语法来产生一个 Range。 ArrayBuffer 就类似于 Java中的 ArrayList。
List
List 代表一个不可变的列表。
List 的创建:
代码语言:javascript复制val list = List(1,2,3,4)
List 有 head 和 tail,head 代表List 的第一个元素,tail 代表第一个元素之后的所有元素。
代码语言:javascript复制val list = List(1,2,3,4)
list.head
list.tail
List 有特殊的 :: 操作符,可以用于将 head 和 tail 合并成一个 List。
代码语言:javascript复制val list = List(1,2,3,4)
0::list
// List(0,1,2,3,4)
1::list
// List(1,1,2,3,4)
如果一个 List 只有一个元素,那么它的 head 就是这个元素,它的tail是Nil。
代码语言:javascript复制val list = List(1)
list.head
// Int = 1
list.tail
// List[Int] = List()
案例:用递归函数来给 List 中每个元素都加上指定前缀并打印(加上指的是打印出的效果)。
代码语言:javascript复制def func(prefix:String, list:List[Int]){
if(list != Nil){
println(prefix list.head)
func(prefix,list.tail)
}
}
LinkedList
LinkedList 代表一个可变的列表,使用 elem 可以引用其头部,使用next 可以引用其尾部。
代码语言:javascript复制val list = scala.collection.mutable.LinkedList(1,2,3,4,5)
list.elem
// Int = 1
list.next
// scala.collection.mutable.LinkedList[Int] = LinkedList(2, 3, 4, 5)
案例:使用 while 循环将LinkedList 中的每个元素都乘以 2 。
代码语言:javascript复制val list = scala.collection.mutable.LinkedList(1,2,3,4,5)
var currentList = list
while(currentList != Nil){
currentList.elem = currentList.elem * 2
currentList = currentList.next
}
案例:使用 while 循环将LinkedList 中,从第一个元素开始,每隔一个元素,乘以 2 。
Set
Set 代表一个没有重复元素的集合,将重复元素加入 Set 是没有用的。
而且 Set 是不保证插入顺序的,也就是说,Set 中的元素是乱序的。
代码语言:javascript复制val s = new scala.collection.mutable.HashSet[Int]();
s = 1
s = 2
s = 5
LinkedHashSet 会用一个链表维护插入顺序。
代码语言:javascript复制val s = new scala.collection.mutable.LinkedHashSet[Int]()
s = 1
s = 2
s = 5
SrotedSet 会自动根据 key 来进行排序。
代码语言:javascript复制val s = scala.collection.mutable.SortedSet("orange", "apple", "banana")
// 按字典序排序
val ss = scala.collection.mutable.SortedSet(4,2,3)
// 默认是从小到大
集合的函数式编程
集合的函数式编程非常非常非常之重要!!! Scala 的集合类的 map、flatMap、reduce、reduceLeft、foreach 等这些函数,就是高阶函数,因为可以接收其他函数作为参数。
高阶函数的使用,也是 Scala 与Java 的不同。因为 Java 里面是没有函数式编程的,也肯定没有高阶函数,也肯定无法直接将函数传入一个方法,或者让一个方法返回一个函数。
代码语言:javascript复制// map 练习:为List中每个元素都添加一个前缀
List("Li", "Chy", "Ln").map("name is " _)
// faltMap 练习:将List中的多行句子拆分成单词
List("Hello World", "Like You").flatMap(_.split(" "))
// foreach 练习:打印 List 中的每个单词
List("I","have","a","girlfriend").foreach(println(_))
// zip 练习:对学生姓名和学生成绩进行关联
List("Li", "Hcy", "chy").zip(List(100, 100, 99))
函数式编程综合案例:统计多个文本内的单词总数
代码语言:javascript复制val line1 = scala.io.Source.fromFile("C://Users//12895//Desktop//text1.txt").mkString
val line2 = scala.io.Source.fromFile("C://Users//12895//Desktop//text2.txt").mkString
// 这里的文本中单词都是空格分开的。
val lines = List(line1,line2)
lines.flatMap(_.split(" ")).map((_,1)).map(_._2).reduceLeft(_ _)
// lines.flatMap(_.split(" ")) 以空格为分隔符,分割单词
// lines.flatMap(_.split(" ")).map((_,1)) 每个单词计数
// lines.flatMap(_.split(" ")).map((_,1)).map(_._2) 拿出来个数
// lines.flatMap(_.split(" ")).map((_,1)).map(_._2).reduceLeft(_ _) 依次相加