• Scala的基本语法:集合应用


    集合应用

    map映射操作

    将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集合。

    相当于def map[泛型](f: (A) ⇒ B): HashSet[泛型]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhFuWgEt-1575173838451)(…/…/…/MarkdownPictures/scala/1565874704650.png)]

    flatmap映射

    flat即压扁 将集合中的每个元素的子元素映射到某个函数并返回新的集合。

    val names = List("Alice", "Bob", "Nick")
    def upper( s : String ) : String = {
        s. toUpperCase
    }
    //得到list(A,L,I,C,E,B,O,B,N,I,C,K)
    

    filter集合元素的过滤

    filter:将符合要求的数据(筛选)放置到新的集合中,filter()里的函数返回值类型必须是布尔值

    val names2 = names.filter(startA)  // 如果startA 返回一个true,则加入到新集合中,否则,过滤
    

    fold折叠

    fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list(集合)中的所有元素被遍历。同外部reduce

    1. reduceLeft相当于简化版的foldLeft,fold函数传入的参数也可以是引用类型比如对象

    2. fold,foldLeft,foldRight 使用同reduce相似

      val list = List(1, 2, 3, 4) def minus( num1 : Int, num2 : Int ): Int = { num1 - num2}
      println(list.foldLeft(5)(minus))//等价对化简 List(5,1,2,3,4)等于minus(minus(minus(minus(5,1),2),3),4)) =-5 
      println(list.foldRight(5)(minus)) // minus(1,minus(2,minus(3,minus(4,5)))) = 3 
      
    3. foldLeft和foldRight 缩写方法分别是:/:和:\

    reduce化简

    化简:将二元函数引用于集合中的函数 相当于折叠的集合内操作

    scala推荐的算法是递归,所以reduce都是两两操作

    1. reduceLeft(f) 从左向右化简,接收的函数需要的形式为 op: (B, A) => B): B

      val list = List(1, 20, 30, 4, 5)
      val sum1 = list.reduceLeft(sum1)// 无需输入()
      def sum1(n1: Int, n2: Int): Int =  n1 + n2
      //List(1, 20, 30, 4, 5)相当于sum(sum(sum(sum(1, 20), 30), 4),5)
      
    2. reduceRight(f)跟reduceLeft(f)相反 从右往左

    3. reduce(f)跟reduceLeft(f)一样

    4. reduceByKey

    scan扫描

    扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果(包含输入的参数)放置于一个集合(vector)中保存

    1. 用法 类似fold
    2. scanRight 传入的都在最右边
    def minus( num1 : Int, num2 : Int ) : Int = { num1 - num2} 
    def add( num1 : Int, num2 : Int ) : Int = {num1 + num2}
    val i8 = (1 to 5).scanLeft(5)(minus) //5(1,2,3,4,5) 等价(5, 4, 2,-1,-5,-10)
    vector(5, 4, 2,-1,-5,-10)
    val i9 = (1 to 5).scanRight(5)(add) 
    vector(20,19,17,14,10,5) 
    

    练习题

    课堂练习2
    val sentence = “AAAAAAAAAABBBBBBBBCCCCCDDDDDDD”
    使用映射集合,统计一句话中,各个字母出现的次数
    提示:Map[Char, Int]()
    使用scala的flodLeft折叠方式实现

     def main(args: Array[String]): Unit = {
        val sentence = "AAAAAABBCCDDDDDD"
        var map1 = Map[Char, Int]()
        val map2 = sentence.foldLeft(map1)(charCount)
        println("map2=" + map2)
        println("map1=" + map1)
    
        //使用charCount2,生产
        var map3 = mutable.Map[Char, Int]()
        sentence.foldLeft(map3)(charCount2)
    
        println("map3=" + map3)
      }
    
      //说明
      //1. map : Map[Char, Int] : 左折叠时传入的第一个参数,返回的类型也是Map[Char, Int]
      //2. c : Char, 因为从 "AAAABCC..." 每次取出的元素就是 Char
      //3. map + (k -> v) // 如果k 没有就是增加,如果存在,是修改
      //4. map.getOrElse(c, 0) + 1 => 统计当前 c 出现的次数
      def charCount( map : Map[Char, Int], c : Char ): Map[Char, Int] = {
        map + (c -> (map.getOrElse(c, 0) + 1)) //不可变map
      }
      //使用可变的Map 玩一把
      def charCount2(map : mutable.Map[Char, Int], c : Char ): mutable.Map[Char, Int] = {
        map += (c -> (map.getOrElse(c, 0) + 1)) //不可变map
      }
    
    

    扩展

    拉链

    将两个集合进行 对偶元组合并

    val list1 = List(1, 2 ,3)
    val list2 = List(4, 5, 6)
    println(list1.zip(list2)) //List((1,4), (2,5), (3,6))
    
    1. 拉链的本质就是两个集合的合并操作,合并后每个元素是一个 对偶元组
    2. 如果两个集合个数不对应,会造成数据丢失。
    3. 集合不限于List, 也可以是其它集合比如 Array
    4. 如果要取出合并后的各个对偶元组的数据,可以按元组方法遍历
    for(item<-list3){ print(item._1 + " " + item._2) //取出时,按照元组的方式取出即可  }
    

    迭代器

    通过iterator方法从集合获得一个迭代器,通过while循环和for表达式对集合进行遍历

    val iterator = List(1, 2, 3, 4, 5).iterator // 得到迭代器
        println("--------遍历方式1 -----------------")
        while (iterator.hasNext) {
            println(iterator.next())
        }
        println("--------遍历方式2 for -----------------")
    val iterator2 = List(11, 22, 33, 44, 55).iterator // 得到迭代器
        for(enum <- iterator2) {
          println(enum) //
        }
    
    1. iterator 的构建实际是 AbstractIterator 的一个匿名子类,该子类提供了
        def iterator: Iterator[A] = new AbstractIterator[A] {
        var these = self
        def hasNext: Boolean = !these.isEmpty
        def next(): A = 
    
    1. 该AbstractIterator 子类提供了 hasNext next 等方法.
    2. 如果需要重新迭代,重新获取迭代器
    3. 可以使用 while的方式,使用hasNext next 方法变量
  • 相关阅读:
    设计模式外观模式
    SQL Server高级查询
    电脑双屏下如何设置程序在第二屏幕运行
    Vistual Studio自带的计划任务功能
    SQL Server定时创建动态表
    访问网站出现空白页面的原因和解决方法
    微软老将Philip Su的离职信:回首12年职场生涯的心得和随笔
    SQL Server更改字段名
    刷新本页与父页的两条代码
    色彩感情
  • 原文地址:https://www.cnblogs.com/successok/p/14737324.html
Copyright © 2020-2023  润新知