Scala零基础教学【21-40】
第24讲:Scala中SAM转换实战详解
第25讲:Scala中Curring实战详解
从数学的角度讲,这是一个对函数消元求解的过程:
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)