第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(, , , , ) 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】的更多相关文章

  1. Scala零基础教学【1-20】

    基于王家林老师的Spark教程——共计111讲的<Scala零基础教学> 计划在9月24日内完成(中秋节假期之内) 目前18号初步学习到25讲,平均每天大约完成15讲,望各位监督. 初步计 ...

  2. Scala零基础教学【102-111】Akka 实战-深入解析

    第102讲:通过案例解析Akka中的Actor运行机制以及Actor的生命周期 Actor是构建akka程序的核心基石,akka中actor提供了构建可伸缩的,容错的,分布式的应用程序的基本抽象, a ...

  3. Scala零基础教学【90-101】Akka 实战-代码实现

    第90讲:基于Scala的Actor之上的分布式并发消息驱动框架Akka初体验 akka在业界使用非常广泛 spark背后就是由akka驱动的 要写消息驱动的编程模型都首推akka 下面将用30讲讲解 ...

  4. Scala零基础教学【81-89】

    第81讲:Scala中List的构造是的类型约束逆变.协变.下界详解 首先复习四个概念——协变.逆变.上界.下界 对于一个带类型参数的类型,比如 List[T]: 如果对A及其子类型B,满足 List ...

  5. Scala零基础教学【61-80】

    第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析 第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析 /** ...

  6. Scala零基础教学【41-60】

    第41讲:List继承体系实现内幕和方法操作源码揭秘 def main(args: Array[String]) { /** * List继承体系实现内幕和方法操作源码揭秘 * * List本身是一个 ...

  7. Android零基础入门第40节:自定义ArrayAdapter

    原文:Android零基础入门第40节:自定义ArrayAdapter ListView用起来还是比较简单的,也是Android应用程序中最重要的一个组件,但其他ListView可以随你所愿,能够完成 ...

  8. Scala实战高手****第2课:Scala零基础实战入门的第一堂课及如何成为Scala高手

    val声明的不可变的战略意义:1.函数式编程中要求值不可变,val天然符合这一特性:2.在分布式系统中,一般都要求值不可变,这样才能够要求分布式系统的设计和实现,同时拥有更高的效率,val声明的内容都 ...

  9. C语言基础:数组 分类: iOS学习 c语言基础 2015-06-10 21:40 7人阅读 评论(0) 收藏

    数组:是由一组具有相同数据类型的数据组合而来. 数组定义:元素类型修饰符 数组名[数组个数]={元素1,元素2....};  int arr[ 2 ]={1,2};    //正确 int arr[ ...

随机推荐

  1. Android百度地图的使用

    做关于位置或者定位的app的时候免不了使用地图功能,本人最近由于项目的需求需要使用百度地图的一些功能,所以这几天研究了一下,现写一下blog记录一下,欢迎大家评论指正! 一.申请AK(API Key) ...

  2. hdu 6223 Infinite Fraction Path

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6223 题意:给定长度为n的一串数字S,现在要按照一种规则寻找长度为n的数字串,使得该数字串的字典序最大 ...

  3. P3076 [USACO13FEB]出租车Taxi

    题目描述 Bessie is running a taxi service for the other cows on the farm. The cows have been gathering a ...

  4. SQL优化之一

    使用union代替or,可以提升查询效率. 使用or时,会自动放弃已有的索引

  5. windows下mysql 5.7的配置全过程

    这是一套在好多次的安装下总结出来的经验,包括很多种遇到的问题,查过很多资料,特此总结一下. 一.从官网下载MySQL的zip(免安装的) 解压mysql-5.7.11-winx64.zip到自己指定的 ...

  6. POJ2495(棋盘分治,染色)

    Incomplete chess boards Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2483   Accepted ...

  7. POJ3264(线段树求区间最大最小值)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 41162   Accepted: 19327 ...

  8. doxygen使用

    前言 下面主要讲解linux下Doxygen命令行实现html文档生成的操作,当然也有界面版本操作方式,linux下安装doxygen-gui即可通过doxywizard开启界面操作,windows下 ...

  9. python基础===socket模块的讲解(转)

    一.网络知识的一些介绍 socket 是网络连接端点.例如当你的Web浏览器请求www.jb51.net上的主页时,你的Web浏览器创建一个socket并命令它去连接 www.jb51.net的Web ...

  10. 【POI2017||bzoj4726】Flappy Birds

    外国人很良心的啊,这题比NOIP那题还简单…… 不用管他最后的位置,因为移动的次数肯定是恒定的,所以维护在每一个柱子的位置能飞到的范围,递推下去即可. #include<bits/stdc++. ...