Flink实时大数据处理技术 课件 02章.Scala语言_第1页
Flink实时大数据处理技术 课件 02章.Scala语言_第2页
Flink实时大数据处理技术 课件 02章.Scala语言_第3页
Flink实时大数据处理技术 课件 02章.Scala语言_第4页
Flink实时大数据处理技术 课件 02章.Scala语言_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章Scala语言Flink实时大数据处理技术教学内容第一节Scala语言概述第二节Scala语言入门第三节集合第四节函数式编程第五节面向对象编程第六节模式匹配教学目标知识目标了解Scala语言的基本语法和特性技能目标掌握Scala语言基本语法的核心操作毕业要求 1.工程知识Scala语言概述–知识点预览#节知识点难点重点应用1C02-01Scala语言概述1、Scala简介√

2、开发环境配置√3、创建项目√Scala简介Scala(全称:ScalableLanguage)是一种通用的、支持面向对象编程和函数式编程的编程语言。最初是为了在Java虚拟机(JVM)上提供更好的可扩展性而创建的。Scala的语法结构源自于Java和ML语言,它旨在融合面向对象编程和函数式编程的最佳特性,以提高程序的可读性、灵活性和扩展性。Scala和Java一样,都是运行在Java虚拟机上的编程语言。Scala代码可以与Java代码无缝地集成,也可以使用Java库,反之亦然。Scala还具有一些Java所没有的功能和优势,例如更丰富的函数式编程特性、支持类型推断和隐式转换、更灵活的语法等等。Scala简介Scala是一种多范式编程语言,具有以下几个特点:面向对象函数式编程JVM兼容性模式匹配隐式参数和隐式转换并发和异步编程开发环境配置—下载安装JavaSE采用的Scala版本为2.12.x,此版本需要保证JDK为1.8及以上版本。在Windows上配置Scala环境如下:首先,需要到Oracle官网下载并安装JDK(JavaDevelopmentKit),具体步骤如下:打开网址/java/technologies/javase-downloads.html在JavaSE下载页面中,选择适合自己操作系统的版本(如Windows、macOS等),

然后点击“下载”按钮。同意许可协议并下载相应版本的安装程序。下载完成后,运行安装程序,按照指示完成JDK的安装。开发环境配置—配置Java环境变量安装完成后,需要配置JAVA_HOME环境变量。在Windows操作系统中,可以按照以下步骤进行配置:打开“控制面板”,进入“系统和安全”选项,点击“系统”。在系统界面中,点击“高级系统设置”。在“系统属性”窗口中,点击“环境变量”。在“环境变量”窗口中,点击“新建”按钮,输入变量名JAVA_HOME,变量值为JDK

的安装路径(如C:\ProgramFiles\Java\jdk1.8.0_271)。在“环境变量”窗口中,找到系统变量中的“Path”变量,点击“编辑”按钮,在变量值

的末尾添加;%JAVA_HOME%\bin,表示将JDK的bin目录添加到系统路径中。点击“确定”按钮,保存修改并关闭窗口。配置完成后,可以在命令行输入java-version命令,如果可以正常输出版本信息,则表示JDK安装成功,并且JAVA_HOME环境变量配置成功。开发环境配置—下载安装配置Scala从官网/下载适合自己操作系统的Scala安装包,然后解压到一个不包含中文及空格的路径下。以下为Scala的环境变量配置:新建变量SCALA_HOME,值为Scala安装路径(例如C:\Program\scala)。编辑变量Path,在末尾添加%SCALA_HOME%\bin;,保存退出。环境变量设置后,打开命令行提示符,验证是否配置成功,输入scala-version指令,回车后,如果显示Scala版本信息,则表示安装成功,然后配置Scala开发环境。开发环境配置—IDEA环境配置由于IDEA默认不支持Scala语言的开发,需要安装Scala插件进行扩展。打开IDEA,依次点击File=>Settings=>Plugins选项卡,在搜索框中搜索Scala插件,找到插件后进行安装。安装完成后,需要重启IDEA以使插件生效,如图所示。图2-1IDEA安装Scala插件创建项目—选择Maven选项在安装Scala插件后,创建项目时,左侧选项中会增加创建Scala项目的选项,由于,后面的Flink项目除了涉及Scala代码,也可能会编写Java代码,选择创建Maven项目更为通用,因此,此处选择Maven选项。图2-2选择Maven选项创建项目—选择Scala框架填写项目名称后,按提示创建项目。由于创建的是Maven项目,还需要添加Scala框架的支持。右键点击项目名称,选择“AddFrameworkSupport”选项,在弹出的窗口中选择Scala框架,完成Scala框架的添加,如图所示。图2-3选择Scala框架创建项目—新建ScalaClass类添加完成后,在项目结构中,找到“src/main/java”目录,右键单击该目录,选择“New->ScalaClass”。如下图所示:图2-4新建Scala类创建项目—选择object选项因为在Scala语言中,程序的入口点是一个单例对象而不是一个类,因此在创建类时需要选择"Object"选项,如图所示:图2-5选择”Object”选项创建项目—编写程序在新建的Demo文件中加入以下示例代码,就可以完成一个基本的Scala程序。然后点击"Run"按钮或使用快捷键"Shift+F10"运行程序,在控制台中即可看到输出"Hello,world!"。objectDemo{defmain(args:Array[String]):Unit={print("helloworld");}}objectDemo:定义了一个名为Demo的对象。defmain(args:Array[String]):Unit=:定义了一个名为main的方法,该方法有一个

参数args,类型为Array[String],并且返回值类型为Unit,表示没有返回值。print("helloworld"):在main方法中,使用print方法打印了字符串"helloworld"。Scala语言入门–知识点预览#节知识点难点重点应用1C02-02Scala语言入门1、类型体系结构√

2、变量的定义与使用√3、字面量与插值表达式√4、运算符√5、流程控制语句√类型体系结构Scala数据类型体系图如下所示,可以划分以下层次:顶级类型:Any和AnyRef,所有Scala类的超类都是Any。AnyRef是所有引用类的超类。值类型和引用类型,值类型的变量直接存储值,引用类型的变量存储的是对实际值的引用。图2-6Scala数据类型体系图变量的定义与使用在Scala中,变量可以使用var和val关键字定义。其中,var关键字定义的变量是可变的,可以修改其值,类似于Java中的变量;val关键字定义的变量是不可变的,一旦初始化后,其值就不能被修改,类似于Java中的常量。//定义一个可变变量varvariableName:variableType=initialValue//定义一个不可变变量valvariableName:variableType=initialValue变量的定义语法如下代码所示:变量的使用非常简单,直接使用变量名即可://定义一个可变变量vara:Int=10a=20println(a)//输出20//定义一个不可变变量valb:Int=30//b=40//报错,val变量不能重新赋值println(b)输出30需要注意的是,一般情况下建议使用不可变变量,因为不可变变量的值在初始化后就不能被修改,可以更好地避免由于变量值被修改而导致的错误。只有在必要的情况下才使用可变变量。变量的定义与使用

Scala支持类型推断,编译器可以自动推断出一个变量或表达式的类型,因此在大多数情况下不需要显式地指定变量的类型。示例代码如下:valx=10//类型推断为Intvaly="hello“//类型推断为String在这里,编译器会根据变量的初始值来推断变量的类型。在需要显式指定类型的情况下,可以使用冒号(:)符号来指定类型。示例代码如下:valx:Int=10//显式指定类型为Intvaly:String="hello“//显式指定类型为String当变量的类型被显式指定时,如果变量的初始值与指定的类型不匹配,则会导致编译错误。类型推断在Scala中非常常见,因为Scala的类型系统非常强大,并且Scala编译器可以根据表达式的上下文来推断类型。字面量与插值表达式—字面量在Scala中,每种类型都有其对应的字面量表示方式,下面是一些常见类型的字面量表示:整数类型(Byte、Short、Int、Long)可以使用十进制、八进制、十六进制和二进制表示,例如:123,0x12AB,0o765,0b1010。浮点数类型(Float、Double)可以使用十进制表示,也可以使用科学计数法表示,例如:1.23,1.23e5。布尔类型(Boolean)有两个字面量值:true和false。字符类型(Char)使用单引号包含一个字符,例如:'a'。字符串类型(String)使用双引号包含一组字符,例如:"hello"。Scala提供了“”“...”“”语法,通过三个双引号来表示原生字符串和多行字符串,使用该种方式,原生字符串中的特殊字符不会被转义,它们的语法如下代码所示:valmultiLineString="""Thisisamulti-linestringwithtriplequotes."""字面量与插值表达式—插值表达式在Scala中,插值表达式(InterpolationExpression)可以让我们在字符串字面量中使用变量或表达式。Scala提供了三种插值方式:s插值、f插值和raw插值。f插值与s插值类似,不同的是可以指定格式化参数,格式化参数的语法与C语言的printf函数相似。示例代码如下:valpi=3.1415926println(f"Piisapproximately$pi%1.2f.")//输出结果为:Piisapproximately3.14.

s插值是最常用的插值方式,它使用$符号来引用变量或表达式,可以使用${}来明确变量或表达式的范围。示例代码如下:valname="Tom"valage=20println(s"Mynameis$name,I'm$ageyearsold.")//输出结果为:MynameisTom,I'm20yearsold.字面量与插值表达式—插值表达式

raw插值与s插值类似,但是它不会将反斜杠字符\转义为其转义字符。在需要打印特殊字符的场景下,可以使用raw插值。示例代码如下:可以看到,使用raw插值输出的结果中,反斜杠字符\并没有被转义成其转义字符,而是按照原本的样子输出了出来。println(raw"Hello\nWorld")//输出结果为:Hello\nWorld字面量与插值表达式—运算符

Scala和其他语言一样,支持大多数的操作运算符,如表所示:varx=10;vary=20;varz=x+y;println("x+y="+z);//输出结果为:x+y=30

Scala支持加减乘除等常见的算术运算符,示例代码如下:表2-1Scala操作运算符字面量与插值表达式—运算符

Scala支持各种比较运算符,示例代码如下:varx=60;vary=13;println("(x&y)="+(x&y));println("(x|y)="+(x|y));println("(x^y)="+(x^y));println("~x="+(~x));

Scala也支持位运算符,包括按位AND、按位OR、按位XOR等,示例代码如下:varx=10;vary=20;if(x>y){println("x>y");}else{println("x<=y");//输出结果为:x<=y

Scala支持逻辑运算符包括AND、OR和NOT代码如下:varx=true;vary=false;println("x&&y="+(x&&y));println("xIly="+(xIly));println("!x="+!x);//输出结果为:x&&y=falsex||y=true!x=false//输出结果(x&y)=12(x|y)=61(x^y)=49~X=-61字面量与插值表达式—运算符

Scala也支持各种赋值运算符,示例代码如下:varx=10;x+=5;//等价于x=x+5println("x="+x);//输出结果为:x=15在Scala中,没有单独的自增和自减运算符++和--,而是通过+=1和-=1来实现的。具体而言,对于一个变量x,x+=1相当于x=x+1,而x-=1相当于x=x-1,示例代码如下:varx=10x+=1//自增1,相当于x=x+1println(x)//输出11x-=1//自减1,相当于x=x-1println(x)//输出10字面量与插值表达式—流程控制语句If-else条件表达式if(condition){//如果条件为真,执行此处代码}else{//如果条件为假,执行此处代码}下面是一个if语句的演示程序,示例代码如下:objectIfElseDemo{defmain(args:Array[String]){valx=5if(x<0){println("xisnegative")}elseif(x>0){println("xispositive")}else{println("xiszero")}}}Scala中的if-else语句用于根据某个条件执行不同的代码块。其语法格式如下:字面量与插值表达式—流程控制语句while循环与do-while循环while(条件){

//循环体}示例代码如下:vari=0while(i<5){println(s"当前数字为$i")i+=1}while循环的语法结构如下:Scala支持while和do-while两种循环语句,用于执行一定的操作直到条件不成立为止。输出结果字面量与插值表达式—流程控制语句while循环与do-while循环do{

//循环体}while(条件)示例代码如下:vari=0do{println(s"当前数字为$i")i+=1}while(i<5)do-while循环的语法结构如下:do-while循环与while循环的区别在于,do-while循环会先执行一次循环体,再进行条件判断。输出结果字面量与插值表达式—流程控制语句for循环for(i<-1to10){println(i)}可以加入until关键字,示例代码如下:for(i<-1until10){println(i)}传统的for循环形式如下:嵌套的for循环形式如下:for(i<-1to3;j<-1to3){println(s"($i,$j)")}for循环可用于遍历集合中的元素代码如下:vallist=List("apple","banana","cherry")for(fruit<-list){println(fruit)}字面量与插值表达式—流程控制语句for循环vallist=List("apple","banana","cherry")for(fruit<-listiffruit.startswith("a")){println(fruit)}for循环可以在循环时添加过滤条件,只有满足条件的元素才会被遍历,代码如下:for循环使用了yield关键字,可以将遍历的元素存储到一个集合中返回,代码如下:vallist=List("apple","banana","cherry")valresult=for(fruit<-listiffruit.startswith("a"))yieldfruitprintln(result)for循环使用了循环守卫,循环守卫可以确保只有当特定的条件满足时,循环才会继续进行,代码如下:for(i<-1to10ifi%2==0){println(i)}字面量与插值表达式—流程控制语句循环控制importscala.util.control.Breaks.breakable{for(i<-1to10){if(i==5)breakelseprintln(i)}}Scala中没有像Java中的break和continue这样的关键字,但是可以使用breakable方法和if表达式来实现类似的效果。breakable方法可以将一个代码块标记为可中断的,然后在代码块中使用break关键字来跳出循环。示例代码如下:在这个例子中,使用breakable方法将for循环块标记为可中断的。当循环计数器i等于5时,使用break语句跳出循环。字面量与插值表达式—流程控制语句Match-case语句inputmatch{casepattern1=>action1casepattern2=>action2case_=>defaultAction}Match-case语句是Scala中的一种模式匹配语法,可以用于根据不同的输入参数执行不同的逻辑。它类似于其他编程语言中的switch语句,但更加灵活和强大。其中,input是要匹配的输入参数,casepattern是模式匹配的表达式,=>后面是要执行的逻辑。每一个case子句都包括了一个模式和一个动作,如果输入参数和模式匹配成功,就会执行对应的动作。Match-case语句的基本语法如下:使用match-case语句对不同的颜色进行匹配如下:defprintColor(color:String):Unit=colormatch{case"red"=>println("Colorisred")case_=>println("Unknowncolor")case"blue"=>println("Colorisblue")case"green"=>println("Colorisgreen")}printColor("red")printColor("yellow")集合–知识点预览#节知识点难点重点应用1C02-03集合1、集合概述

2、Array和ArrayBuffer√3、Tuple√4、List和ListBuffer√5、Set√6、Map√7、集合操作符号√集合概述Scala集合体系结构主要包含可变集合和不可变集合两种类型。可变集合是指在集合的操作过程中可以对其进行修改,而不可变集合则是指在集合的操作过程中不会修改集合的内容。Scala集合体系结构可以分为三个层次,分别是:顶层:

Iterable、Seq、Map、Set等,scala.collection包集合结构。中层:集合的中层包括scala.collection.immutable和scala.collection.mutable两个包。底层:集合的底层是scala.collection.mutable和scala.collection.immutable包中的具体集合类实现。集合概述图2-7scala.collection包集合结构图Array和ArrayBuffer在Scala中,Array和ArrayBuffer都是可变的序列,可以进行添加、删除和修改等操作。不同之处在于:Array是一个固定大小的序列,一旦创建就无法改变它的大小。Array-Buffer可以动态地增加或减少元素数量。Array的创建方式有两种,一种是使用Array伴生对象的apply方法,另一种是使用A-rray类的构造方法。下面是两种方式的示例代码://使用apply方法创建Arrayvalarray1=Array(1,2,3,4,5)//使用构造方法创建Arrayvalarray2=newArray[Int](5)array2(0)=1array2(1)=2array2(2)=3array2(3)=4array2(4)=5Array和ArrayBufferArrayBuffer的创建方式是使用ArrayBuffer类的构造方法。下面是一个示例代码:importscala.collection.mutable.ArrayBuffervalbuffer=ArrayBuffer(1,2,3,4,5)对于Array和ArrayBuffer,常见的操作包括添加元素、删除元素和修改元素等。以A-rrayBuffer为例,以下是一些常用的操作,示例代码如下:importscala.collection.mutable.ArrayBuffer//创建一个空的ArrayBuffervalbuffer=ArrayBuffer[Int]

()//添加元素buffer+=1//在尾部添加元素buffer+=2buffer++=Array(3,4)//在尾部添加一个数组的元素buffer.insert(1,5)//在索引1处插入元素5//删除元素buffer-=4//删除元素4buffer.remove(2)//删除索引2处的元素//修改元素buffer(0)=0//修改索引0处的元素为0Array和ArrayBufferScala中的Array和ArrayBuffer都可以与Java中的数组进行转换。将Java数组转换为Scala数组,可以使用Array伴生对象的apply方法,示例代码如下:valjavaArr=Array("a","b","c")valscalaArr=Array.apply(javaArr:_*)将Scala数组转换为Java数组,可以使用Scala数组的toArray方法,代码中调用方法时省略了括号,示例代码如下:valscalaArr=Array("a","b","c")valjavaArr=scalaArr.toArray//或者使用Java的Arrays类的asList方法importjava.util.ArraysvalscalaArr=Array("a","b","c")valjavaArr=Arrays.asList(scalaArr:_*)TupleTuple(元组)是一个不可变的、有序的、可以容纳不同类型元素的容器。Tuple可以将多个不同类型的值封装在一起,形成一个完整的数据单元。Tuple的元素可以通过下标访问,下标从1开始计数,也可以使用tuple._1、tuple._2等方式进行访问。Scala中的Tuple最多可以包含22个元素,分别是Tuple1、Tuple2、Tuple3直到Tuple22。Tuple常用于需要将多个值作为一个整体处理的场景,例如函数返回多个值、元组作为Map中的键值对等。下面是一个示例程序,演示了如何创建Tuple并访问它的元素://创建一个包含两个元素的元组valtuple=(1,"Scala")//访问元组的第一个元素valfirst=tuple._1//访问元组的第二个元素valsecond=tuple._2//打印元素值println(first)//输出1println(second)//输出"Scala"List和ListBuffer在Scala中,List和ListBuffer都是用来表示序列的集合类型。List是不可变的序列,可以使用::操作符在头部添加元素,但不能在尾部添加元素。它的元素类型可以是任意类型,但所有元素类型必须相同。List的常用操作包括head、tail、isEmpty、l-ength等。List的应用场景包括不需要频繁添加和删除元素的场景,例如配置文件的读取、程序参数的处理等,示例代码如下://创建一个包含整数的Listvallist1=List(1,2,3,4,5)//创建一个包含字符串的Listvallist2=List("apple","banana","orange")//在List头部添加元素vallist3="pear"::list2//获取List头部元素valhead=list3.head//获取List尾部元素valtail=list3.tail//判断List是否为空valisEmpty=list3.isEmpty//获取List的长度vallength=list3.lengthList和ListBuffer列表的其他常用操作方法如下:表2-2列表的其他常用操作方法List和ListBufferListBuffer的应用场景包括需要频繁添加和删除元素的场景,例如日志记录、缓存数据等,示例代码如下://创建一个空的ListBuffervallistBuffer=ListBuffer[Int]()//在ListBuffer尾部添加元素listBuffer+=1listBuffer+=2listBuffer+=3//在ListBuffer头部添加元素4+=:listBuffer5+=:listBuffer//在指定位置插入元素listBuffer.insert(2,0)//删除指定元素listBuffer-=3//删除指定位置的元素listBuffer.remove(0)//将ListBuffer转换为Listvallist=listBuffer.tolistSet在Scala中,Set是一个集合,用于存储唯一的元素。它可以是可变的(mutable)或不可变的(immutable)。使用Set的主要场景是为了保证集合中不会出现重复的元素。例如,我们可以使用Set来统计一段文本中有多少个不同的单词。以下是使用不可变Set的示例代码://创建不可变Setvalset1=Set(1,2,3,4,5)valset2=Set(4,5,6,7,8)//打印集合元素println(set1)//Set(1,2,3,4,5)//向集合中添加元素valset3=set1+6println(set3)//Set(1,2,3,4,5,6)//求两个集合的交集、并集和差集valintersect=ersect(set2)//交集valunion=set1.union(set2)//并集valdiff=set1.diff(set2)//差集//打印集合操作结果println(intersect)//Set(4,5)println(union)//Set(1,2,3,4,5,6,7,8)println(diff)//Set(1,2,3)总的来说,Set可以用于处理需要去重的数据,例如统计单词频率、过滤重复数据等。在具体应用场景中,可以根据需要选择不可变或可变的Set。MapMap是Scala集合框架中的一种集合类型,用于存储键值对。它可以用于各种应用场景,如缓存、配置文件、数据存储等。在Scala中,Map有不可变和可变两种类型,它们分别在scala.collection.immutab-le和scala.collection.mutable包中定义。不可变Map的键值对不能被修改,而可变Map的键值对可以被修改。以下是使用不可变Map的示例代码:创建一个不可变Mapvalmap=Map("a"->1,"b"->2,"c"->3)//访问Map中的元素vala=map("a")valb=map.get("b")//遍历Mapfor((key,value)<-map){println(s"key:$key,value:$value")}//添加元素valnewMap=map+("d"->4)//删除元素valdelMap=map-"c"Map以下是使用可变Map的示例代码://创建一个可变Mapvalmap=scala.collection.mutable.Map("a"->1,"b"->2,"c"->3)//访问Map中的元素vala=map("a")valb=map.get("b")//遍历Mapfor((key,value)<-map){println(s"key:$key,value:$value")}//添加元素map+=("d"->4)//删除元素map-="c"集合操作符号在Scala中,集合操作中的符号是一些预定义的操作符,它们用于对集合进行操作,如元素添加、删除、连接等。Scala集合操作符号列表如下:表2-3Scala集合操作符号列表集合操作符号可以使用+运算符向一个列表中添加一个元素,示例代码如下:vallist=List(1,2,3)valnewList=list+4println(newlist)//输出List(1,2,3,4)valset1=Set(1,2,3)valset2=Set(3,4,5)valnewSet=set1++set2println(newSet)//输出Set(1,2,3,4,5)可以使用++运算符连接两个集合,示例代码如下:函数式编程–知识点预览#节知识点难点重点应用1C02-04函数式编程1、函数的定义与使用√

2、匿名函数√3、高阶函数√4、柯里化雨闭包√函数的定义与使用Scala的函数式编程指的是一种编程范式,它强调函数的重要性和使用不可变值来构建应用程序。在函数式编程中,函数被视为一等公民(first-classcitizens),可以像其他数据类型一样被操作和传递。在Scala中,函数是一等公民,也就是说,函数可以被视为变量一样进行传递和使用。函数的定义由函数名、参数列表、返回值类型和函数体组成。Scala中的函数定义格式如下:函数的调用可以像Java一样使用函数名和参数列表的形式进行。Scala中的函数调用格式如下:deffunctionName(param1:Type1,param2:Type2,...):ReturnType={//函数体…}valresult=functionName(arg1,arg2,...)函数的定义与使用下面是一个简单的函数示例:下面是一个无返回值函数的例子:defadd(x:Int,y:Int):Int={x+у}valresult=add(1,2)println(result)//输出3defprintMessage(message:String):Unit={println(message)}定义了一个名为add的函数,该函数有两个参数x和y,返回值类型为Int,函数体为将两个参数相加。然后我们调用add函数,并将返回值赋给result变量,最后输出result的值为3。无返回值函数的定义方式是在函数签名后面添加Unit类型,表示该函数不会返回任何值。一般情况下,我们可以省略Unit类型的声明,因为Scala编译器会自动推断出函数的返回类型。匿名函数在Scala中,函数可以是命名函数也可以是匿名函数。匿名函数是一种没有函数名的函数,也称为lambda函数。匿名函数通常用于函数参数,或在需要时定义函数。匿名函数的语法如下:其中,(parameter1:type1,parameter2:type2,...)是参数列表,expression是函数体表达式,例如:匿名函数的应用场景包括:作为高阶函数的参数:可以将匿名函数作为高阶函数的参数,用于对集合等数据结构进行遍历、过滤、映射等操作。简化代码:可以使用匿名函数代替一些简单的函数,从而减少代码量,提高代码的可读性。(parameter1:type1,parameter2:type2,...)=>expressionvaladd=(x:Int,y:Int)=>x+yvalsquare=(x:Int)=>x*x高阶函数高阶函数:是指可以接受一个或多个函数作为参数,并/或者返回一个函数作为结果的函数。在Scala中,函数也是一等公民,可以像值一样传递、返回、赋值给变量等。高阶函数的应用场景包括但不限于:函数组合:将多个函数组合成一个新函数,实现函数复用和代码简洁化。回调函数:将函数作为参数传递给其他函数,以实现回调机制。函数柯里化:将接收多个参数的函数转化为接收一个参数的函数序列,以实现函数的分步传递和复用。控制抽象:将函数作为参数传递给高阶函数,以实现控制程序流程和代码抽象化。高阶函数下面是一个使用高阶函数的示例子://定义一个接收两个参数和一个函数的高阶函数defoperate(x:Double,y:Double,f:(Double,Double)=>Double):Double={f(x,y)}//定义两个函数defadd(x:Double,y:Double):Double=x+ydefsubtract(x:Double,y:Double):Double=x-y//调用高阶函数并传入函数参数valresult1=operate(3,2,add)valresult2=operate(3,2,subtract)//输出结果println(result1)//5.0Println(result2)//1.0高阶函数内置高阶函数:map函数将一个集合中的每个元素应用一个函数,并将结果组成一个新的集合返回。flatMap函数将一个集合中的每个元素应用一个返回集合的函数,并将结果扁平化为一个集合返回。filter函数将一个集合中的元素按照给定的条件过滤,并返回一个新的集合。reduce函数将一个集合中的元素依次应用一个二元函数,将结果聚合为一个值。vallist=List(1,2,3)valresult=list.map(x=>x*2)//List(2,4,6)valresult=list.flatMap(x=>List(x,x*2))//List(1,2,2,4,3,6)valresult=list.filter(x=>x%2==0)//List(2)valresult=list.reduce((x,y)=>x+y)//6柯里化与闭包—函数柯里化函数柯里化是一种将接受多个参数的函数转换成接受单一参数(或更少参数)的函数序列的技术。具体来说,就是把一个接受多个参数的函数转化为多个接受单一参数的函数,这些函数每个都返回一个新函数,直到最后一个函数返回结果为止。函数柯里化的主要应用场景是在函数式编程中,它可以让函数更加灵活,可复用,可组合,并且可以使用部分参数调用等特性。下面是一个示例:defmultiply(x:Int)(y:Int):Int=x*y//调用方式1valmultiplyByTwo=multiply(2)_println(multiplyByTwo(5))//输出10//调用方式2println(multiply(3)(4))//输出12柯里化与闭包—闭包闭包(closure)是指一个函数与其相关的引用环境组合而成的实体。简单来说,闭包是一个函数和定义该函数的词法环境的组合。闭包的应用场景有很多,比如:面向对象编程中,闭包可以用来实现私有变量和方法,即将需要隐藏的变量和方法定义在一个函数中,然后返回这个函数。这样,这个函数的作用域中的变量和方法就只能在函数内部被访问到,从而达到了隐藏的目的。在异步编程中,闭包可以用来保持异步调用中的上下文信息。比如,在回调函数中保存一些变量信息,使得回调函数能够访问到这些变量,并进行处理。defmultiplyBy(factor:Int)=(x:Int)=>factor*x//创建一个闭包,其中factor=2valdoubler=multiplyBy(2)//创建一个闭包,其中factor=3valtripler=multiplyBy(3)//使用闭包进行计算println(doubler(5))//输出:10println(tripler(5))//输出:15面向对象编程–知识点预览#节知识点难点重点应用1C02-05面向对象编程1、类与对象√

2、构造器√3、继承√4、伴生类与伴生对象√5、多态√6、泛型√7、隐式转换√类与对象

在Scala中,类和对象是封装数据和行为的基本工具。类是一种模板,用于描述一组有相同属性和方法的对象。对象是类的实例,具有该类定义的属性和方法。FlinkCDC在Scala中,类定义使用关键字class,类中定义的成员包括字段和方法,以下是一个简单的类定义示例:要创建一个类的实例,可以使用关键字new,如下所示:classPerson(varname:String,varage:Int){defsayHello():Unit={println(s"Hello,mynameis$nameandI'm$ageyearsold.")}}objectMain{defmain(args:Array[String]):Unit={valperson=newPerson("Alice",30)person.sayHello()}}构造器构造器(Constructor)是一种特殊的方法,用于创建和初始化对象。在Scala中,每个类都可以有一个主构造器和多个辅助构造器。主构造器在类名后面的括号中声明,主构造器中的参数会被自动转换为类的成员变量。可以通过在类名后面的括号中定义参数来定义主构造器,如下所示。:以下是一个定义了一个辅助构造器的示例:classPerson(name:String,age:Int){println(s"Creatingpersonwithname$nameandage$age")}classPerson(name:String,age:Int){defthis(name:String)=this(name,0)}继承—基本使用继承是面向对象编程中的一种机制,它允许新的类(子类)从已有的类(父类)中继承属性和方法。子类可以使用父类的方法和属性,也可以重写父类的方法和属性,还可以定义自己的方法和属性。继承的应用场景很多,例如:对于一些具有相似特征的类,可以将它们共有的属性和方法放在一个父类中,子类只需要继承父类即可,避免了代码冗余。子类可以在父类的基础上进行扩展和修改,实现更复杂的功能。继承还可以实现多态,子类对象可以作为父类对象来使用,这样可以提高代码的灵活性和可扩展性。//定义一个父类AnimalclassAnimal(varname:String,varage:Int){defeat(food:String):Unit={println(s"$nameiseating$food")}}//定义一个子类Dog,继承自AnimalclassDog(name:String,age:Int,varbreed:String)extendsAnimal(name,age){overridedefeat(food:String):Unit={println(s"$namethe$breediseating$food")}defbark():Unit={println(s"$namethe$breedisbarking")}}//创建Animal和Dog对象,并调用方法valanimal=newAnimal("Tom",3)animal.eat("meat")//Tomiseatingmeatvaldog=newDog("Jack",2,"Labrador")dog.eat("bone")//JacktheLabradoriseatingbonedog.bark()//JacktheLabradorisbarking继承—方法重写方法重写(MethodOverriding)是指子类重新定义父类中已有的方法,以便覆盖父类中的方法。在Scala中,方法重写需要使用override关键字。方法的应用场景:子类需要对父类中的某个方法进行改进或修改实现方式。子类需要添加一些额外的逻辑或特定的行为。classAnimal{defsound():String="animalsound“}classCatextedsAnimal{overridedefsound():String="meow“}valanimal:Animal=newAnimal()println(animal.sound())//输出:"animalsound“valcat:Animal=newCat()println(cat.sound())//输出:"meow"继承—抽象类抽象类是一种不能直接被实例化的类,通常用于定义具有共同特征的类的基类。它包含抽象方法和非抽象方法。抽象方法没有实现,需要由继承抽象类的子类来实现。abstractclass类名{//抽象方法def方法名(参数列表):返回值类型//非抽象方法def方法名(参数列表):返回值类型={//方法体}//属性val属性名:类型“}在Scala中,定义抽象类需要使用关键字“abstract”,并且至少有一个抽象方法。抽象类可以有非抽象方法和属性。定义抽象类的语法格式如下:继承—抽象类抽象类通常用于定义具有共同特征的类的基类,比如一个图形类的基类Shape,包含所有图形的共同特征和方法。示例如下://定义一个抽象类Shape,包含一个抽象方法area和一个非抽象方法drawabstractclassShape{//抽象方法defarea():Double//非抽象方法defdraw():Unit={println("Drawing...")}}//定义Circle和Rectangle两个子类,继承自Shape抽象类,并实现area方法classCircle(r:Double)extendsShape{defarea():Double=3.14*r*r}classRectangle(w:Double,h:Double)extendsShape{defarea():Double=w*h}//创建Circle和Rectangle对象,调用area方法和draw方法valcircle=newCircle(2.0)println("Circlearea:"+circle.area())circle.draw()valrect=newRectangle(2.0,3.0)println("Rectanglearea:"+rect.area())rect.draw()//输出结果伴生类与伴生对象在Scala中,类和对象是分开定义的。一个类可以有多个对象,每个对象有自己的状态,但类只有一个,类的状态是所有对象共享的。classMyClass(valname:String){defhello():Unit=println(s"Hello,$name!")}objectMyClass{privatevarcount=0defgetCount:Int=countdefnewMyClass(name:String):MyClass={count+=1newMyClass(name)}}伴生类和伴生对象是一对相互关联的类和对象。它们之间可以互相访问彼此的私有成员,且它们必须在同一个源文件中定义。objectMainextendsApp{valobj1=MyClass.newMyClass("Alice")valobj2=MyClass.newMyClass("Bob")println(obj1.hello())//Hello,Alice!println(obj2.hello())//Hello,Bob!println(MyClass.getCount)//2}多态—基本概念多态是指同一类型的对象,在不同情况下的表现形式和行为不同。在面向对象的编程中,多态是实现代码重用和灵活性的重要手段之一。在Scala中,多态可以通过继承和重写实现。abstractclassAnimal{defmakeSound():String}classDogextendsAnimal{overridedefmakeSound():String="Woof"}classCatextendsAnimal{overridedefmakeSound():String="Meow“}在Scala中,多态可以通过继承和重写实现。下面是一个使用多态的示例:objectMain{defanimalSound(animal:Animal):String={animal.makeSound()}defmain(args:Array[String]):Unit={valdog=newDog()valcat=newCat()println(animalSound(dog))//输出:Woofprintln(animalSound(cat))//输出:Meow}}多态—特质特质(Trait)是Scala中一种特殊的抽象类型,类似于Java中的接口(interface),但是比接口更加强大。特质可以包含方法、抽象字段、具体字段、构造器以及类型定义等内容,而且可以被类和对象混入(mixin)使用,增强它们的功能。trait特质名{//可以包含抽象方法、具体方法、抽象字段、具体字段、构造器以及类型定义等}使用特质可以方便地实现代码的复用和组合。特质提供了一种接口的实现方式,特质的语法如下:traitLogger{deflog(msg:String):Unit=println(s"log:$msg")}classPerson(valname:String)classStudent(name:String)extendsPerson(name)withLogger{defstudy(subject:String):Unit=log(s"$nameisstudying$subject")}valstudent=newStudent("Tom")student.study(“Math”)//输出:log:TomisstudyingMath下面是一个使用特质的例子:模式匹配–知识点预览#节知识点难点重点应用1C02-06模式匹配1、基本使用√

2、条件守卫√3、常用匹配√4、样例类√基本使用模式匹配(PatternMatching)是Scala中一种强大的语言特性,它可以对一个值进行多个可能情况的匹配,从而执行对应的操作。模式匹配可用于匹配基本数据类型、集合、样例类、正则表达式等各种数据类

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论