zoukankan      html  css  js  c++  java
  • 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两个包。

    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。

    案例:使用while循环将LinkedList中每个一个元素乘以二。

    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代表一个没有重复元素的集合

    HashSet

    不保证插入顺序,元素是乱序的

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

  • 相关阅读:
    深度学习面试题03:改进版梯度下降法Adagrad、RMSprop、Momentum、Adam
    深度学习面试题02:标准梯度下降法
    深度学习面试题01:导数、偏导数、方向导数、梯度的概念
    2014.09.14(西安绿点)
    直接拿来用!最火的Android开源项目(完结篇)
    直接拿来用!最火的Android开源项目(二)
    直接拿来用!最火的Android开源项目(一)
    直接拿来用!最火的iOS开源项目(三)
    直接拿来用!最火的iOS开源项目(二)
    直接拿来用!最火的iOS开源项目(一)
  • 原文地址:https://www.cnblogs.com/LiCheng-/p/8045108.html
Copyright © 2011-2022 走看看