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(, , , , ) partition (_ % ==))
//find:查找集合第一个符合条件的元素
println(List(, , , , ) find (_ % ==))
println(List(, , , , ) find (_ <=))
//takeWhile:着个匹配符合条件的元素 直到不符合条件 之后的元素不在判断
println(List(, , , , ) takeWhile (_ < ))
//dropWhile:着个匹配去除符合条件的元素 直到不符合条件 之后的元素不在判断
println(List(, , , , ) dropWhile (_ < ))
//span 着个匹配按照某种条件对数据进行分类 直到不符合条件 之后的元素不在判断
println(List(, , , , ) span (_ < )) //forall 当所有的元素满足条件时 返回true 否则返回false
//exists 当存在(至少有一个满足)元素满足条件时 返回true 否则返回false
def hastotallyZeroRow(m: List[List[Int]]) = m exists (row => row forall (_ == ))
val m= List(List(,,), List(,,), List(,,))
println(List(,,) forall(_==))
println(List(,,) forall(_==))
println(List(,,) forall(_==))
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)
Scala零基础教学【21-40】的更多相关文章
- Scala零基础教学【1-20】
基于王家林老师的Spark教程——共计111讲的<Scala零基础教学> 计划在9月24日内完成(中秋节假期之内) 目前18号初步学习到25讲,平均每天大约完成15讲,望各位监督. 初步计 ...
- Scala零基础教学【102-111】Akka 实战-深入解析
第102讲:通过案例解析Akka中的Actor运行机制以及Actor的生命周期 Actor是构建akka程序的核心基石,akka中actor提供了构建可伸缩的,容错的,分布式的应用程序的基本抽象, a ...
- Scala零基础教学【90-101】Akka 实战-代码实现
第90讲:基于Scala的Actor之上的分布式并发消息驱动框架Akka初体验 akka在业界使用非常广泛 spark背后就是由akka驱动的 要写消息驱动的编程模型都首推akka 下面将用30讲讲解 ...
- Scala零基础教学【81-89】
第81讲:Scala中List的构造是的类型约束逆变.协变.下界详解 首先复习四个概念——协变.逆变.上界.下界 对于一个带类型参数的类型,比如 List[T]: 如果对A及其子类型B,满足 List ...
- Scala零基础教学【61-80】
第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析 第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析 /** ...
- Scala零基础教学【41-60】
第41讲:List继承体系实现内幕和方法操作源码揭秘 def main(args: Array[String]) { /** * List继承体系实现内幕和方法操作源码揭秘 * * List本身是一个 ...
- Android零基础入门第40节:自定义ArrayAdapter
原文:Android零基础入门第40节:自定义ArrayAdapter ListView用起来还是比较简单的,也是Android应用程序中最重要的一个组件,但其他ListView可以随你所愿,能够完成 ...
- Scala实战高手****第2课:Scala零基础实战入门的第一堂课及如何成为Scala高手
val声明的不可变的战略意义:1.函数式编程中要求值不可变,val天然符合这一特性:2.在分布式系统中,一般都要求值不可变,这样才能够要求分布式系统的设计和实现,同时拥有更高的效率,val声明的内容都 ...
- C语言基础:数组 分类: iOS学习 c语言基础 2015-06-10 21:40 7人阅读 评论(0) 收藏
数组:是由一组具有相同数据类型的数据组合而来. 数组定义:元素类型修饰符 数组名[数组个数]={元素1,元素2....}; int arr[ 2 ]={1,2}; //正确 int arr[ ...
随机推荐
- tomcat内存配置及配置参数详解
1.jvm内存管理机制: 1)堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟 ...
- Ant Design 使用小结
最近公司做了一个系统,因为页面涉及的表单交互非常多,如果使用之前的 Node + Express 的开发模式效率是非常低的,因此经过考虑,最后决定使用 Node + React 的开发模式,并且使用了 ...
- Python基础(7)闭包函数、装饰器
一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用 那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() ...
- 【BZOJ1996】【HNOI2010】合唱队 [区间DP]
合唱队 Time Limit: 4 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description Input Output Sample ...
- bzoj4602 [Sdoi2016]齿轮
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4602 [题解] 对于每组齿轮(u, v)连边,权值为y/x(反向边x/y) 那么直接dfs计 ...
- bzoj3223 文艺平衡树 codevs3303 翻转区间
splay模版题吧 只有区间翻转 至于为什么要把须翻转区间旋到根 因为查找一个区间可以先找出他左端点左边第一个点和右端点x右边第一个点y 然后将x旋到根节点 y旋到x的右儿子 这样x的右边的点就是所有 ...
- 【CF1027F】Session in BSU(dsu,基环树)
题意:给出n场考试,每场考试有2天可以通过(第ai与bi天).每天最多参加一场考试,现在要求所有考试全部通过的最小天数 n<=1e6,1<=a[i]<b[i]<1e9 思路:F ...
- 02-更改窗口的根控制器
Demo示例程序源代码
源代码下载链接:02-更改窗口的根控制器.zip18.0 KB // MJAppDelegate.h // // MJAppDelegate.h // 02-更改窗口的根控制器 // // ...
- Linux 下编译安装OpenCV【转】
转自:http://www.cnblogs.com/emouse/archive/2013/02/22/2922940.html OpenCV 2.2以后版本需要使用Cmake生成makefile文件 ...
- 最新Python异步编程详解
我们都知道对于I/O相关的程序来说,异步编程可以大幅度的提高系统的吞吐量,因为在某个I/O操作的读写过程中,系统可以先去处理其它的操作(通常是其它的I/O操作),那么Python中是如何实现异步编程的 ...