书签 分享 收藏 举报 版权申诉 / 120
上传文档赚钱

类型第1章-Scala-语言基础-(Spark精品课件.ppt

  • 上传人(卖家):三亚风情
  • 文档编号:2881254
  • 上传时间:2022-06-07
  • 格式:PPT
  • 页数:120
  • 大小:5.31MB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《第1章-Scala-语言基础-(Spark精品课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    Scala 语言 基础 Spark 精品 课件
    资源描述:

    1、Scala Scala 语言基础语言基础汇报人:日期:目录目录2Scala基础3面向对象编程基础1Scala语言概述4函数式编程基础ScalaScala语语言概述言概述l Scala运行于Java虚拟机(JVM)之上,因此只要安装有相应的Java虚拟机,所有的操作系统都可以运行Scala程序,包括Window、Linux、Unix、 Mac OS等。lScala是一门类Java的多范式语言,它整合了面向对象编程和函数式编程的最佳特性。具体来讲:Scala运行于Java虚拟机(JVM)之上,并且兼容现有的Java程序Scala是一门纯粹的面向对象的语言Scala也是一门函数式语言 安装安装Sca

    2、laScala登录Scala官网,下载scala-2.11.8.tgz把scala命令添加到path环境变量中启动Scala解释器:使用使用ScalaScala解释器解释器在Shell命令提示符界面中输入“scala”命令后,会进入scala命令行提示符状态:可以使用命令“:quit”退出Scala解释器,如下所示第一个第一个ScalaScala程序:程序:HelloWorldHelloWorld 注意,上面命令中一定要加入-classpath .,否则会出现“No such file or class on classpath: HelloWorld”目录目录2Scala基础3面向对象编程基

    3、础1Scala语言概述4函数式编程基础ScalaScala声明和变量声明和变量Scala有两种类型的变量:val:是不可变的,在声明时就必须被初始化,而且初始化以后就不能再赋值;var:是可变的,声明的时候需要进行初始化,初始化以后还可以再次对其赋值ScalaScala声明和变量声明和变量ScalaScala声明和变量声明和变量ScalaScala声明和变量声明和变量小技巧:如何在Scala解释器中输入多行代码基本数据类型和操作基本数据类型和操作Scala的数据类型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean和Java不同的是,在Scala中

    4、,这些类型都是“类”,并且都是包scala的成员,比如,Int的全名是scala.Int。对于字符串,Scala用java.lang.String类来表示字符串基本数据类型和操作基本数据类型和操作字面量(literal)基本数据类型和操作基本数据类型和操作操作符:在Scala中,可以使用加(+)、减(-) 、乘(*) 、除(/) 、余数(%)等操作符,而且,这些操作符就是方法。例如,5 + 3和(5).+(3)是等价的,也就是说:等价于前者是后者的简写形式,这里的+是方法名,是Int类中的一个方法。和Java不同,在Scala中并没有提供+和-操作符,当需要递增和递减时,可以采用如下方式表达:

    5、基本数据类型和操作基本数据类型和操作富包装类富包装类对于基本数据类型,除了以上提到的各种操作符外,Scala还提供了许多常用运算的方法,只是这些方法不是在基本类里面定义,还是被封装到一个对应的富包装类中。每个基本类型都有一个对应的富包装类,例如Int有一个RichInt类、String有一个RichString类,这些类位于包scala.runtime中。当对一个基本数据类型的对象调用其富包装类提供的方法,Scala会自动通过隐式转换将该对象转换为对应的富包装类型,然后再调用相应的方法。例如:3 max 5。RangeRange在执行for循环时,我们经常会用到数值序列,比如,i的值从1循环到

    6、5,这时就可以采用Range来实现。Range可以支持创建不同数据类型的数值序列,包括Int、Long、Float、Double、Char、BigInt和BigDecimal等。(1)创建一个从1到5的数值序列,包含区间终点5,步长为1RangeRange(2)创建一个从1到5的数值序列,不包含区间终点5,步长为1(3)创建一个从1到10的数值序列,包含区间终点10,步长为2(4)创建一个Float类型的数值序列,从0.5f到5.9f,步长为0.3f控制台输入输出语句控制台输入输出语句为了从控制台读写数据,可以使用以read为前缀的方法,包括:readInt、readDouble、readBy

    7、te、readShort、readFloat、readLong、readChar readBoolean及readLine,分别对应9种基本数据类型,其中前8种方法没有参数,readLine可以不提供参数,也可以带一个字符串参数的提示。所有这些函数都属于对象scala.io.StdIn的方法,使用前必须导入,或者直接用全称进行调用控制台输入输出语句控制台输入输出语句控制台输入输出语句控制台输入输出语句为了向控制台输出信息,常用的两个函数是print()和println(),可以直接输出字符串或者其它数据类型控制台输入输出语句控制台输入输出语句Scala还带有C语言风格的格式化字符串的print

    8、f()函数print()、println()和printf() 都在对象Predef中定义,该对象默认情况下被所有Scala程序引用,因此可以直接使用Predef对象提供的方法,而无需使用scala.Predef.的形式。读写文件读写文件写入文件写入文件Scala需要使用java.io.PrintWriter实现把数据写入到文件如果我们想把文件保存到一个指定的目录下,就需要给出文件路径读写文件读写文件读取文件读取文件可以使用Scala.io.Source的getLines方法实现对文件中所有行的读取异常处理异常处理Scala仍使用try-catch结构来捕获异常import java.io.F

    9、ileReader import java.io.FileNotFoundException import java.io.IOException try val f = new FileReader(input.txt) / 文件操作 catch case ex: FileNotFoundException = / 文件不存在时的操作 case ex: IOException = / 发生I/O错误时的操作 finally file.close() / 确保关闭文件 Scala不支持Java中的“受检查异常”(checked exception),将所有异常都当作“不受检异常”(或称为运行时

    10、异常)if if表达式表达式有一点与Java不同的是,Scala中的if表达式的值可以赋值给变量whilewhile循环循环forfor循环循环Scala中的for循环语句格式如下:其中,“变量-表达式”被称为“生成器(generator)”forfor循环循环不希望打印出所有的结果,过滤出一些满足制定条件的结果,需要使用到称为“守卫(guard)”的表达式比如,只输出1到5之中的所有偶数,可以采用以下语句:forfor循环循环Scala也支持“多个生成器”的情形,可以用分号把它们隔开,比如:forfor循环循环可以给每个生成器都添加一个“守卫”,如下:forfor循环循环Scala的for结

    11、构可以在每次执行的时候创造一个值,然后将包含了所有产生值的集合作为for循环表达式的结果返回,集合的类型由生成器中的集合类型确定通过for循环遍历一个或多个集合,对集合中的元素进行“推导”,从而计算得到新的集合,用于后续的其他处理forfor (变量 Xiamen University, THU - Tsinghua University,PKU-Peking University)映射(映射(MapMap)如果要获取映射中的值,可以通过键来获取对于这种访问方式,如果给定的键不存在,则会抛出异常,为此,访问前可以先调用contains方法确定键是否存在映射(映射(MapMap)不可变映射,是无

    12、法更新映射中的元素的,也无法增加新的元素。如果要更新映射的元素,就需要定义一个可变的映射也可以使用+=操作来添加新的元素映射(映射(MapMap)循环遍历映射循环遍历映射或者,也可以只遍历映射中的k或者v迭代器(迭代器(IteratorIterator)在Scala中,迭代器(Iterator)不是一个集合,但是,提供了访问集合的一种方法迭代器包含两个基本操作:next和hasNext。next可以返回迭代器的下一个元素,hasNext用于检测是否还有下一个元素迭代器(迭代器(IteratorIterator)scala val xs = List(1, 2, 3, 4, 5)xs: List

    13、Int = List(1, 2, 3, 4, 5)scala val git = xs grouped 3git: IteratorListInt = non-empty iteratorscala git.next()res3: ListInt = List(1, 2, 3)scala git.next()res4: ListInt = List(4, 5)scala val sit = xs sliding 3sit: IteratorListInt = non-empty iteratorscala sit.next()res5: ListInt = List(1, 2, 3)scala

    14、 sit.next()res6: ListInt = List(2, 3, 4)scala sit.next()res7: ListInt = List(3, 4, 5)Iterable有两个方法返回迭代器:grouped和sliding。然而,这些迭代器返回的不是单个元素,而是原容器(collection)元素的全部子序列。这些最大的子序列作为参数传给这些方法。grouped方法返回元素的增量分块,sliding方法生成一个滑动元素的窗口。两者之间的差异通过REPL的作用能够清楚看出。数组(数组(ArrayArray)数组是一种可变的、可索引的、元素具有相同类型的数据集合,它是各种高级语言中

    15、最常用的数据结构。Scala提供了参数化类型的通用数组类ArrayT,其中T可以是任意的Scala类型,可以通过显式指定类型或者通过隐式推断来实例化一个数组。可以不给出数组类型,Scala会自动根据提供的初始化数据来推断出数组的类型数组(数组(ArrayArray)Array提供了函数ofDim来定义二维和三维数组,用法如下:valval myMatrix = Array.ofDimInt(3,4) /类型实际就是ArrayArrayIntvalval myCube = Array.ofDimString(3,2,4) /类型实际是ArrayArrayArrayInt可以使用多级圆括号来访问多

    16、维数组的元素,例如myMatrix(0)(1)返回第一行第二列的元素数组(数组(ArrayArray)采用Array类型定义的数组属于定长数组,其数组长度在初始化后就不能改变。如果要定义变长数组,需要使用ArrayBuffer参数类型,其位于包scala.collection.mutable中。举例如下:import import scala.collection.mutable.ArrayBuffervalval aMutableArr = ArrayBuffer(10,20,30) aMutableArr += 40 aMutableArr.insert(2, 60,40) aMutabl

    17、eArr -= 40 varvar temp=aMutableArr.remove(2) 元组元组元组是不同类型的值的聚集。元组和列表不同,列表中各个元素必须是相同类型,而元组可以包含不同类型的元素目录目录2Scala基础3面向对象编程基础1Scala语言概述4函数式编程基础简单的类简单的类最简单的类的定义形式是:可以使用new关键字来生成对象给类增加字段和方法给类增加字段和方法如果大括号里面只有一行语句,那么也可以直接去掉大括号,写成下面的形式:或者,还可以去掉返回值类型和等号,只保留大括号,如下:Unit后面的等号和大括号后面,包含了该方法要执行的具体操作语句创建对象创建对象下面我们新建对

    18、象,并调用其中的方法:从上面代码可以看出,Scala在调用无参方法时,是可以省略方法名后面的圆括号的编译和执行编译和执行新建一个TestCounter.scala代码文件在Linux Shell命令提示符下,使用scala命令执行这个代码文件:上面命令执行后,会在屏幕输出“1”编译和执行编译和执行也可以进入到Scala解释器下面去执行TestCounter.scala 首先启动Scala解释器,如下:进入scala命令提示符状态以后,可以在里面输入如下命令:完成上面操作以后,可以退出Scala解释器,回到Linux系统的Shell命令提示符状态,退出Scala解释器的命令如下:编译和执行编译和

    19、执行下面尝试一下,看看是否可以使用scalac命令对这个TestCounter.scala文件进行编译,如下:执行上述scalac命令后,会出现一堆错误,无法编译。为什么呢?原因:声明都没有被封装在对象中,因此,无法编译成JVM字节码编译和执行编译和执行在TestCounterJVM.scala中输入以下代码:使用scalac命令编译这个代码文件,并用scala命令执行,如下:上面命令执行后,会在屏幕输出“1”$ scalac TestCounterJVM.scala$ scala -classpath . MyCounter /MyCounter是包含main方法的对象名称,这里不能使用文件

    20、名称TestCounterJVM编译和执行编译和执行现在我们对之前的类定义继续改进一下,让方法中带有参数。我们可以修改一下TestCounterJVM.scala文件:编译执行这个文件,就可以得到执行结果是5。gettergetter和和settersetter方法方法给类中的字段设置值以及读取值,在Java中是通过getter和setter方法实现的在Scala中,也提供了getter和setter方法的实现,但是并没有定义成getXxx和setXxx继续修改TestCounterJVM.scala文件:编译执行这个文件,就可以得到两行执行结果,第一行是0,第二行是4。gettergette

    21、r和和settersetter方法方法但是,在Java中,是不提倡设置这种公有(public)字段的,一般都是把value字段设置为private,然后提供getter和setter方法来获取和设置字段的值。那么,到了Scala中该怎么做呢?现在我们去用scalac命令编译上面的代码,就会报错,会出现“error:variable value in class Counter cannot be accessed in Counter”这样的错误信息。因为,value字段前面用了修饰符private,已经成为私有字段,外部是无法访问的。我们先把value字段声明为private,看看会出现什么

    22、效果,继续修改TestCounterJVM.scala文件:gettergetter和和settersetter方法方法value变成私有字段以后,Scala又没有提供getter和setter方法,怎么可以访问value字段呢?解决方案是,在Scala中,可以通过定义类似getter和setter的方法,分别叫做value和value_=,具体如下:编译执行这个文件,就可以得到三行执行结果,第一行是0,第二行是3,第三行是4。辅助构造器辅助构造器Scala构造器包含1个主构造器和若干个(0个或多个)辅助构造器辅助构造器的名称为this,每个辅助构造器都必须调用一个此前已经定义的辅助构造器或主

    23、构造器下面定义一个带有辅助构造器的类,我们对上面的Counter类定义进行修改:(代码未完,剩余代码见下一页)辅助构造器辅助构造器(代码续上一页)编译执行上述代码后,得到右边结果:主构造器主构造器Scala的每个类都有主构造器。但是,Scala的主构造器和Java有着明显的不同,Scala的主构造器是整个类体,需要在类名称后面罗列出构造器所需的所有参数,这些参数被编译成字段,字段的值就是创建对象时传入的参数的值。对于上面给计数器设置name和mode的例子,刚才我们是使用辅助构造器来对name和mode的值进行设置,现在我们重新来一次,这次我们转而采用主构造器来设置name和mode的值。编译

    24、执行上述代码后,得到结果:单例对象单例对象Scala并没有提供Java那样的静态方法或静态字段,但是,可以采用object关键字实现单例对象,具备和Java静态方法同样的功能。下面是单例对象的定义:可以看出,单例对象的定义和类的定义很相似,明显的区分是,用object关键字,而不是用class关键字。单例对象单例对象把上述代码放入到一个test.scala文件中测试在Shell命令提示符下输入scala命令运行上面代码:执行后,屏幕上会显示以下结果:2.3.2.2 2.3.2.2 伴生对象伴生对象在Java中,我们经常需要用到同时包含实例方法和静态方法的类,在Scala中可以通过伴生对象来实现

    25、。当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”。类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法)。伴生对象伴生对象删除并重新创建一个test.scala,在该文件中输入如下代码:运行结果:伴生对象伴生对象从上面结果可以看出,伴生对象中定义的newPersonId()实际上就实现了Java中静态(static)方法的功能Scala源代码编译后都会变成JVM字节码,实际上,在编译上面的源代码文件以后,在Scala里面的class和object在Java层面都会被合二为一,class里面的成员成了实例成员,object成员成了static成员伴生对象

    26、伴生对象为了验证这一点,我们可以一起测试一下。删除并重新创建一个test.scala,在该文件中输入如下代码:这里做一点小小修改,那就是把object Person中的newPersonId()方法前面的private去掉伴生对象伴生对象在Shell命令提示符状态下,输入以下命令编译并执行:在目录下看到两个编译后得到的文件,即Person.class和Person$.class。经过编译后,伴生类和伴生对象在JVM中都被合并到了一起执行结果如下:从结果可以看出,经过编译后,伴生类Person中的成员和伴生对象Person中的成员都被合并到一起,并且,伴生对象中的方法newPersonId(),

    27、成为静态方法忽略Person$.class,只看Person.class。请使用下面命令进行“反编译”:应用程序对象应用程序对象每个Scala应用程序都必须从一个对象的main方法开始重新创建一个test.scala,在该文件中输入如下代码:为了运行上述代码,我们现在可以使用两种不同的方法。第一种方法:直接使用scala命令运行得到结果。第二种方法:先编译再执行applyapply方法和方法和updateupdate方法方法我们经常会用到对象的apply方法和update方法,虽然我们表面上并没有察觉,但是,实际上,在Scala中,apply方法和update方法都会遵循相关的约定被调用,约定

    28、如下:用括号传递给变量(对象)一个或多个参数时,Scala 会把它转换成对apply方法的调用当对带有括号并包括一到若干参数的对象进行赋值时,编译器将调用对象的update方法,在调用时,是把括号里的参数和等号右边的对象一起作为update方法的输入参数来执行调用applyapply方法和方法和updateupdate方法方法下面我们测试一下apply方法是否被调用。删除并重新创建test.scala文件,输入以下代码:在Linux系统的Shell命令提示符下运行scala命令:运行后会得到以下结果:applyapply方法和方法和updateupdate方法方法上面是类中定义了apply方法

    29、,下面看一个在单例对象中定义apply方法的例子:把上面代码放入到test.scala文件中测试执行后,可以得到如下结果:可以看出,在执行TestApplySingleObject(Zhangfei, Liubei)时调用了apply方法,并且把“Zhangfei and Liubei”作为返回值,赋值给group变量,因此,println(group)语句会打印出“Zhangfei and Liubei”。applyapply方法和方法和updateupdate方法方法下面我们测试一个伴生类和伴生对象中的apply方法实例。删除并重新创建test.scala文件,输入以下代码:执行结果如下:

    30、applyapply方法和方法和updateupdate方法方法首先使用scalac编译命令对test.scala进行编译,然后,使用scala命令运行,具体如下:上述代码执行后得到以下结果:从上面代码可以看出,当我们执行val a = ApplyTest()时,会导致apply方法的调用并返回该方法调用的值,也就是ApplyTest的实例化对象。当执行a()时,又会导致调用伴生类的apply方法,如果我们愿意,就可以在伴生类的apply方法中写入一些处理逻辑,这样就可以把传入的参数赋值给实例化对象的变量。applyapply方法和方法和updateupdate方法方法下面看一个apply方法

    31、的例子。由于Scala中的Array对象定义了apply方法,因此,我们就可以采用如下方式初始化一个数组:也就是说,不需要new关键字,不用构造器,直接给对象传递3个参数,Scala就会转换成对apply方法的调用,也就是调用Array类的伴生对象Array的apply方法,完成数组的初始化。applyapply方法和方法和updateupdate方法方法实际上,update方法也是类似的,比如:从上面可以看出,在进行元组赋值的时候,之所以没有采用Java中的方括号myStrArr0,而是采用圆括号的形式,myStrArr(0),是因为存在上述的update方法的机制。ScalaScala与与

    32、JavaJava在继承方面的区别在继承方面的区别Scala中的继承与Java有着显著的不同:(1)重写一个非抽象方法必须使用override修饰符。(2)只有主构造器可以调用超类的主构造器。(3)在子类中重写超类的抽象方法时,不需要使用override关键字。(4)可以重写超类中的字段。Scala和Java一样,不允许类从多个超类继承抽象类抽象类以汽车为例子,首先我们创建一个抽象类,让这个抽象类被其他类继承。关于上面的定义,说明几点:(1)定义一个抽象类,需要使用关键字abstract。(2)定义一个抽象类的抽象方法,也不需要关键字abstract,只要把方法体空着,不写方法体就可以。(3)抽

    33、象类中定义的字段,只要没有给出初始化值,就表示是一个抽象字段,但是,抽象字段必须要声明类型,比如:val carBrand: String,就把carBrand声明为字符串类型,这个时候,不能省略类型,否则编译会报错。扩展类扩展类抽象类不能直接被实例化,所以,下面我们定义几个扩展类,它们都是扩展了Car类,或者说继承自Car类。扩展类扩展类下面,我们把上述代码放入一个完整的代码文件test.scala,编译运行。执行后,屏幕上会显示以下结果:扩展类扩展类在Shell命令提示符下输入scala命令运行上面代码:执行后,屏幕上会显示以下结果:特质概述特质概述Java中提供了接口,允许一个类实现任意

    34、数量的接口在Scala中没有接口的概念,而是提供了“特质(trait)”,它不仅实现了接口的功能,还具备了很多其他的特性Scala的特质,是代码重用的基本单元,可以同时拥有抽象方法和具体方法Scala中,一个类只能继承自一个超类,却可以实现多个特质,从而重用特质中的方法和字段,实现了多重继承特质的定义特质的定义特质的定义和类的定义非常相似,有区别的是,特质定义使用关键字trait。上面定义了一个特质,里面包含一个抽象字段id和抽象方法currentId。注意,抽象方法不需要使用abstract关键字,特质中没有方法体的方法,默认就是抽象方法。把特质混入类中把特质混入类中特质定义好以后,就可以使

    35、用extends或with关键字把特质混入类中。把特质混入类中把特质混入类中下面,我们把上述代码放入一个完整的代码文件test.scala,编译运行。执行结果:特质可以包含具体实现特质可以包含具体实现上面的实例中,特质只包含了抽象字段和抽象方法,相当于实现了类似Java接口的功能。实际上,特质也可以包含具体实现,也就是说,特质中的字段和方法不一定要是抽象的。把多个特质混入类中把多个特质混入类中上面已经定义了两个特质CarId和CarGreeting。可以把两个特质都混入到类中。执行结果如下:简单匹配简单匹配Scala的模式匹配最常用于match语句中。下面是一个简单的整型值的匹配实例。另外,在

    36、模式匹配的case语句中,还可以使用变量。执行结果:类型模式类型模式Scala可以对表达式的类型进行匹配。执行结果: 守卫守卫(guard)(guard)语句语句可以在模式匹配中添加一些必要的处理逻辑。执行结果:forfor表达式中的模式表达式中的模式以我们之前举过的映射为例子,我们创建的映射如下:循环遍历映射的基本格式是:对于遍历过程得到的每个值,都会被绑定到k和v两个变量上执行结果:casecase类的匹配类的匹配case类是一种特殊的类,它们经过优化以被用于模式匹配。执行结果:OptionOption类型类型标准类库中的Option类型用case类来表示那种可能存在、也可能不存在的值。一

    37、般而言,对于每种语言来说,都会有一个关键字来表示一个对象引用的是“无”,在Java中使用的是null。Scala融合了函数式编程风格,因此,当预计到变量或者函数返回值可能不会引用任何值的时候,建议你使用Option类型。Option类包含一个子类Some,当存在可以被引用的值的时候,就可以使用Some来包含这个值,例如Some(Hadoop)。而None则被声明为一个对象,而不是一个类,表示没有值。OptionOption类型类型下面我们给出一个实例。OptionOption类型类型Option类型还提供了getOrElse方法,这个方法在这个Option是Some的实例时返回对应的值,而在是

    38、None的实例时返回传入的参数。例如:可以看出,当我们采用getOrElse方法时,如果我们取的hive没有对应的值,我们就可以显示我们指定的“No Such Book”,而不是显示None。OptionOption类型类型在Scala中,使用Option的情形是非常频繁的。在Scala里,经常会用到OptionT类型,其中的T可以是Sting或Int或其他各种数据类型。OptionT实际上就是一个容器,我们可以把它看做是一个集合,只不过这个集合中要么只包含一个元素(被包装在Some中返回),要么就不存在元素(返回None)。既然是一个集合,我们当然可以对它使用map、foreach或者fil

    39、ter等方法。比如:可以发现,上述代码执行后,屏幕上什么都没有显示,因为,foreach遍历遇到None的时候,什么也不做,自然不会执行println操作。目录目录2Scala基础3面向对象编程基础1Scala语言概述4函数式编程基础函数字面量函数字面量字面量包括整数字面量、浮点数字面量、布尔型字面量、字符字面量、字符串字面量、符号字面量、函数字面量和元组字面量。除了函数字面量我们会比较陌生以外,其他几种字面量都很容易理解。函数字面量函数字面量函数字面量可以体现函数式编程的核心理念。在非函数式编程语言里,函数的定义包含了“函数类型”和“值”两种层面的内容。但是,在函数式编程中,函数是“头等公民

    40、”,可以像任何其他数据类型一样被传递和操作,也就是说,函数的使用方式和其他数据类型的使用方式完全一致了。这时,我们就可以像定义变量那样去定义一个函数,由此导致的结果是,函数也会和其他变量一样,开始有“值”。就像变量的“类型”和“值”是分开的两个概念一样,函数式编程中,函数的“类型”和“值”也成为两个分开的概念,函数的“值”,就是“函数字面量”。函数的类型和值函数的类型和值下面我们一点点引导大家更好地理解函数的“类型”和“值”的概念。我们现在定义一个大家比较熟悉的传统类型的函数,定义的语法和我们之前介绍过的定义“类中的方法”类似(实际上,定义函数最常用的方法是作为某个对象的成员,这种函数被称为方

    41、法):上面定义个这个函数的“类型”如下:实际上,只有多个参数时(不同参数之间用逗号隔开),圆括号才是必须的,当参数只有一个时,圆括号可以省略,如下:上面就得到了函数的“类型”函数的类型和值函数的类型和值下面看看如何得到函数的“值”实际上,我们只要把函数定义中的类型声明部分去除,剩下的就是函数的“值”,如下:注意:上面就是函数的“值”,需要注意的是,采用“=”而不是“=”,这是Scala的语法要求。函数的类型和值函数的类型和值现在,我们再按照大家比较熟悉的定义变量的方式,采用Scala语法来定义一个函数。声明一个变量时,我们采用的形式是:照葫芦画瓢,我们也可以按照上面类似的形式来定义Scala中

    42、的函数:从上面可以看出,在Scala中,函数已经是“头等公民”,单独剥离出来了“值”的概念,一个函数“值”就是函数字面量。这样,我们只要在某个需要声明函数的地方声明一个函数类型,在调用的时候传一个对应的函数字面量即可,和使用普通变量一模一样。匿名函数、匿名函数、LamdaLamda表达式与闭包表达式与闭包我们不需要给每个函数命名,这时就可以使用匿名函数,如下:上面这种匿名函数的定义形式,我们经常称为“Lamda表达式”。“Lamda表达式”的形式如下:我们可以直接把匿名函数存放到变量中,下面是在Scala解释器中的执行过程:匿名函数、匿名函数、LamdaLamda表达式与闭包表达式与闭包实际上

    43、,Scala具有类型推断机制,可以自动推断变量类型,比如下面两条语句都是可以的:所以,上面的定义中,我们可以myNumFunc的类型声明,也就是去掉“Int=Int”,在Scala解释器中的执行过程如下:2.4.1.3 2.4.1.3 匿名函数、匿名函数、LamdaLamda表达式与闭包表达式与闭包下面我们再尝试一下,是否可以继续省略num的类型声明,在Scala解释器中的执行过程如下:可以看出,解释器会报错,因为,全部省略以后,实际上,解释器也无法推断出类型下面我们尝试一下,省略num的类型声明,但是,给出myNumFunc的类型声明,在Scala解释器中的执行过程如下:不会报错,因为,给出

    44、了myNumFunc的类型为“Int=Int”以后,解释器可以推断出num类型为Int类型。匿名函数、匿名函数、LamdaLamda表达式与闭包表达式与闭包闭包是一个函数,一种比较特殊的函数,它和普通的函数有很大区别普通函数:闭包:闭包反映了一个从开放到封闭的过程每次addMore函数被调用时都会创建一个新闭包每个闭包都会访问闭包创建时活跃的more变量占位符语法占位符语法为了让函数字面量更加简洁,我们可以使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次。从上面运行结果可以看出,下面两个函数字面量是等价的。占位符语法占位符语法有时你把下划线当作参数的占位符时,编译器有

    45、可能没有足够的信息推断缺失的参数类型。例如,假设你只是写_ + _: scalavalf=_+_:4:error:missingparametertypeforexpandedfunction(x$1,x$2)=x$1.$plus(x$2)valf=_+_这种情况下,你可以运用 冒号指定类型,如下: scalavalf=(_:Int)+(_:Int)f:(Int,Int)=Int=scalaf(5,10)res11:Int=15请留心 _ + _将扩展成带两个参数的函数字面量。这也是仅当每个参数在函数字面量中最多出现一次的情况下你才能运用 这种短格式的原由 。多个下划线指代多个参数,而不是单个

    46、参数的重复运用 。第一个下划线代表第一个参数,第二个下划线代表第二个,第三个,如此类推。遍历操作遍历操作列表的遍历列表的遍历可以使用for循环进行遍历:也可以使用foreach进行遍历:遍历操作遍历操作映射的遍历映射的遍历循环遍历映射,是经常需要用到的操作,基本格式是:执行结果:创建一个映射循环遍历映射遍历操作遍历操作映射的遍历映射的遍历也可以使用foreach来实现对映射的遍历也可以尝试使用下面形式来遍历mapmap操作和操作和flatMapflatMap操作操作map操作是针对集合的典型变换操作,它将某个函数应用到集合中的每个元素,并产生一个结果集合。mapmap操作操作mapmap操作和

    47、操作和flatMapflatMap操作操作flatMap操作操作flatMap是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个集合(而不是一个元素),然后,flatMap把生成的多个集合“拍扁”成为一个集合。上面的flatMap执行时,会把books中的每个元素都调用toList,生成ListChar,最终,多个Char的集合被“拍扁”成一个集合。filterfilter操作操作遍历一个集合并从中获取满足指定条件的元素组成一个新的集合。Scala中可以通过filter操作来实现。首先创建一个映射:val university = Map(XMU - Xi

    48、amen University, THU - Tsinghua University,PKU-Peking University,XMUT-Xiamen University of Technology) 采用filter操作过滤得到那些学校名称中包含“Xiamen”的元素val universityOfXiamen = university filter kv = kv._2 contains Xiamen 采用filter操作过滤得到那些学校名称中以字母“P”开头的元素:val universityOfP = university filter kv = kv._2 startsWith

    49、P reducereduce操作操作使用reduce这种二元操作对集合中的元素进行归约reduce包含reduceLeft和reduceRight两种操作,前者从集合的头部开始操作,后者从集合的尾部开始操作。reduceLeft(_ + _)整个加法操作的执行顺序如下:reduceRight(_ + _)表示从列表尾部开始,对两两元素进行求和操作,顺序如下:直接使用reduce,而不用reduceLeft和reduceRight,这时,默认采用的是reduceLeftfoldfold操作操作折叠(fold)操作和reduce(归约)操作比较类似。fold操作需要从一个初始的“种子”值开始,并以该值作为上下文,处理集合中的每个元素。fold有两个变体:foldLeft()和foldRight(),其中,foldLeft(),第一个参数为累计值,集合遍历的方向是从左到右。foldRight(),第二个参数为累计值,集合遍历的方向是从右到左。对于fold()自身而言,遍历的顺序是未定义的,不过,一般都是从左到右遍历。函数式编程实例函数式编程实例WordCountWordCountTHANKS!

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:第1章-Scala-语言基础-(Spark精品课件.ppt
    链接地址:https://www.163wenku.com/p-2881254.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库