• Scala零基础教学【21-40】


    第24讲:Scala中SAM转换实战详解

    SAM:single abstract method 单个抽象方法
     
    我们想传入一个函数来指明另一个函数具体化的工作细节,但是重复的样板代码很多。
    我们不关心它实现了什么接口的什么方法,只关心这个动作。比如下面的按钮点击一次,data就加1,而不关心ActionListener以及其回调方法。
    那么就用隐式转换。这个后面会彻底地讲解。
     

    第25讲:Scala中Curring实战详解

     
    柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
     

    从数学的角度讲,这是一个对函数消元求解的过程:

    def f(x:Int,y:Int)=x+y

    def g(x:Int)=f(x,1)

    def z=g(1)

    z=2

    那么z也可以写成这样:def z=(x:Int)=>(y:Int)=>x+y

    例如:

    def add(x:Int,y:Int)=x+y

    柯里化后:

    def add(x:Int)(y:Int)=x+y

    实际实现是scala的语法糖,依次调用两个普通函数,第一次调用函数(x),第二次调用时使用了(x)的返回值。

    def add=(x:Int)=>(y:Int)=>x+y

    那么具体怎么实现柯里化呢?

    假设我原始的普通函数 def add(x:Int,y:Int)=x+y

    目标函数是Int=>Int=>Int (或者Int=>(Int=>Int))

    大概长这样def add=(x:Int)=>(y:Int)=>x+y

    抽象出来是[参数1=>参数2=>function(参数1,参数2)]
    柯里化函数:
           def curry[A,B,C](f: (A, B) => C): A => (B => C) =  a => b => f(a, b)

    curry: [A, B, C](f: (A, B) => C)A => (B => C)

    用柯里化函数调用非柯里化函数add后:

    def add(x:Int,y:Int)=x+y

    def addCurry=curry(add)

    addCurry: Int => (Int => Int)

    测试:

    addCurry(1)(2)

    res10: Int = 3

     
    package com.wanji.scala.function
    
    object Curring {
      
      def main(args: Array[String]): Unit = {
        def multiple(x:Int,y:Int)=x*y
        def multipleOne(x:Int)=(y:Int)=>x*y
        println(multipleOne(6)(7))
        
        def curring(x:Int)(y:Int)=x*y
        
        println(curring(10)(10))
        val a=Array("Hello","Spark")
        val b=Array("Hello","spark")
        println(a.corresponds(b)(_.equalsIgnoreCase(_)))
        
      }
      
    }
    

     

    第28讲:Scala提取器Extractor实战详解 

    第29讲:Case class和Case object代码实战解析

    第30讲:模式匹配高级实战:嵌套的Case class

    第31讲:Option使用和实现内幕源码揭秘

    第36讲:List的partition、find、takeWhile、dropWhile、span、forall、exsists操作代码实战

    val r1 = s1.takeWhile( _ < 10)
    r1: List[Int] = List(1, 2, 3, 4)
    takeWhile是从第一个元素开始,取满足条件的元素,直到不满足为止
     val r2 = s1.filter( _ < 10)
    r2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
    fiter取出所有满足条件的元素
    差异:
    fiter取所有的满足条件的元素;
    takeWhile取出从第一个开始满足条件的元素,直到遇到不满足条件的元素

        println(List(1, 2, 3, 4, 5) partition (_ % 2 ==0))
        //find:查找集合第一个符合条件的元素
        println(List(1, 2, 3, 4, 5) find (_ % 2 ==0))
        println(List(1, 2, 3, 4, 5) find (_  <=0))
        //takeWhile:着个匹配符合条件的元素 直到不符合条件 之后的元素不在判断
        println(List(1, 2, 3, 4, 5) takeWhile (_  < 4))
        //dropWhile:着个匹配去除符合条件的元素 直到不符合条件 之后的元素不在判断
        println(List(1, 2, 3, 4, 5) dropWhile (_  < 4))
        //span 着个匹配按照某种条件对数据进行分类 直到不符合条件 之后的元素不在判断
        println(List(1, 2, 3, 4, 5) span (_  < 4))
    
    
        //forall  当所有的元素满足条件时 返回true 否则返回false
        //exists  当存在(至少有一个满足)元素满足条件时 返回true 否则返回false
        def hastotallyZeroRow(m: List[List[Int]]) = m exists (row => row forall (_ == 0))
        val m= List(List(1,0,0), List(0,0,0), List(0,0,1))
        println(List(1,0,0) forall(_==0))
        println(List(0,0,0) forall(_==0))
        println(List(0,0,1) forall(_==0))
        println(hastotallyZeroRow(m))

    第37讲:List的foldLeft、foldRight、sort操作代码实战

    foldLeft定义:

    def foldLeft[B](z: B)(op: (B, A) => B): B = {
        var result = z
        this.seq foreach (x => result = op(result, x))
        result
    }

    方法接受2个参数,z和op,一个是B类型的参数,一个是返回B类型的函数。

    在看到这个trait其实是TraversableOnce,可迭代的集合。

     def seq: TraversableOnce[A]

    比如一个val listA = List(1,2,3)

    listA其实是实现了TraversableOnce这个trait的。

    我们可以直接使用:

    scala> listA.foldLeft(0)((sum,i)=>sum+i)
    res26: Int = 6

    这个里面的0其实就是z返回值是Int类型即B类型

    那么可以看出op这个函数返回值也需要是Int类型

    可以看出

    val result = z, 这里其实就是0,x=>result=op(result, x) , sum其实也是z

    其实z就是返回值,this.seq在这里就是list,对list遍历,这里执行op函数。

    这里我们执行的是sum+i,就是累加了1+2+3=6

        println(List(1 to 5))
        //传递的参数在左参数
        //(10-1)-2-3-4-5=-5
        println((1 to 5).foldLeft(10)(_-_))
        //传递的参数在右参数,结果在右
        //(1-10)=-9
        //2-(-9)=11
        //3-11=-8
        //4-(-8)=12
        //5-12=-7
        println((1 to 5).foldRight(10)(_-_))
    
     

    第38讲:List伴生对象操作方法代码实战

       //apply:根据元素构建对象
        println(List.apply(1, 2, 3))
        //make:重复构建,第一个参数个数,第二个参数是数值
        println(List.make(3, 5))
        //range:构建元素集合(1,2,3,4)
        println(List.range(1, 5))
        //rang:最后的元素是步长,(9,6,3)
        println(List.range(9, 1, -3))
        
        val zipped = "abcde".toList zip List(1, 2, 3, 4, 5)
        //List((a,1),(b,2),(c,3),(d,4),(e,5))
        println(zipped)
        //(List(a,b,c,d,e),List(1,2,3,4,5))
        println(zipped.unzip)
        //flatten:多个集合中的元素放到一个集合中
        println(List(List('a', 'b'), List('c'), List('d', 'e')).flatten)
        //多个集合拼接,类似flatten
        println(List.concat(List(), List('b'), List('c')))
    
        //map2:索引相同的元素操作之后放入新的集合中
        println(List.map2(List(10, 20), List(10, 10)) (_ * _))
    

      结果:

    List(1, 2, 3)
    List(5, 5, 5)
    List(1, 2, 3, 4)
    List(9, 6, 3)
    List((a,1), (b,2), (c,3), (d,4), (e,5))
    (List(a, b, c, d, e),List(1, 2, 3, 4, 5))
    List(a, b, c, d, e)
    List(b, c)
    List(100, 200)
    

    第39讲:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战

        import scala.collection.mutable.ListBuffer
        //可变的ListBuffer,默认不可变
        val listBuffer = new ListBuffer[Int]
        listBuffer += 1
        listBuffer += 2
        println(listBuffer)
        
        import scala.collection.mutable.ArrayBuffer
        val arrayBuffer = new ArrayBuffer[Int]()
        arrayBuffer += 1
        arrayBuffer += 2
        println(arrayBuffer)
        
        val empty = Queue[Int]()
        //入队列操作 enqueue
        val queue1 = empty.enqueue(1)
        val queue2 = queue1.enqueue(List(2,3,4,5))
        println(queue2)
        //出队列操作 dequeue  def dequeue: (A, Queue[A])
        val (element, left) = queue2.dequeue
        println(element + " : " + left)
        println("immutable:"+queue2)
        println(queue2.dequeue)
        println("immutable为不可变队列:"+queue2)
        
        import scala.collection.mutable.Queue
        val queue3=Queue[Int]()
        queue3++=List(1,2,3,4,5)
        println(queue3.dequeue())
        println("mutable:"+queue3)
    
        val queue = Queue[String]()
        queue += "a"
        queue ++= List("b", "c")
        println(queue)
        println(queue.dequeue)
        println(queue)
        
        import scala.collection.mutable.Stack
        val stack = new Stack[Int]
        stack.push(1)
        stack.push(2)
        stack.push(3)
        //top仅仅是get操作,pop是获取加出栈
        println(stack.top)
        println(stack)
        println(stack.pop)
        println(stack)
    

      

    第40讲:Set、Map、TreeSet、TreeMap操作代码实战

       //Set 无序集合
        val data = mutable.Set.empty[Int]
        data ++= List(1, 2, 3)
        data += 4;
        data --= List(2, 3);
        println(data)
        data += 1;
        println(data)
        data.clear
        println(data)
    
    
        val map = mutable.Map.empty[String, String]
        map("Java") = "Hadoop"
        map("Scala") = "Spark"
        println(map)
        println(map("Scala"))
        //TreeSet 有序的集合
        val treeSet = TreeSet(9, 3, 1, 8, 0, 2, 7, 4, 6, 5)  
        println("有序集合TreeSet:"+treeSet)
        val treeSetForChar = TreeSet("Spark", "Scala", "Hadoop")  
        println(treeSetForChar)
        val treeSet2=TreeSet(0,1,2,3,4,5,6,7,8,9)
    
        println(treeSet2)
        
        var treeMap = TreeMap("Scala" -> "Spark", "Java" -> "Hadoop")
        println(treeMap)
    

      

  • 相关阅读:
    SpringCloud教程五:Zuul(路由+过滤)
    ubuntu18.0.4 不能下载 libgd2-dev
    ubuntu18.04下安装中文输入法
    Ubuntu下tomcat启动报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
    Java面试题汇总(一)
    Redis常见面试题
    Docker是什么
    Django实现自动发布(1数据模型)
    数据随机分配的思考
    单链表反转
  • 原文地址:https://www.cnblogs.com/sunrunzhi/p/9667795.html
Copyright © 2020-2023  润新知