待完成任务
1.安装scala
2.完成三道题
3.游戏数仓项目相关知识点信息
4.第一节课1-13 重难点是集合、函数式编程
第一节课笔记
scala语言课程设计
一、课前准备
- scala语言简介
- scala开发环境搭建
- scala的基础语法
-
三、课堂目标
搭建scala开发环境
- 掌握scala基本语法结构(变量、表达式、if、循环、方法、函数…)
- 掌握scala集合使用(数组、元组、List、Set、Map…)
四、知识要点
1. scala简介
- scala是运行在 JVM 上的多范式编程语言,同时支持==面向对象==和==面向函数编程==
- scala大概是在==2003年==才正式诞生,而java的诞生可以追溯到1995年
- 早期scala刚出现的时候,并没有怎么引起重视,随着==Spark==(2010开源、2014成为apache顶级项目)和==Kafka==这样基于scala的大数据框架的兴起,scala逐步进入大数据开发者的眼帘。
- scala的主要优势是它的==表达性==。
官网地址
- http://www.scala-lang.org
- 养成习惯逛一逛官网
2. 为什么要使用scala
开发大数据应用程序(Spark程序、Flink程序)
- 小厂可能有用java、python
- 基础更扎实一些
- 表达能力强,一行代码抵得上Java多行,开发速度快
- 兼容Java,可以访问庞大的Java类库
3. 开发环境安装
3.3 安装IDEA的scala插件
4. scala的REPL交互式解释器
1. windos下面的REPL使用
val/var 变量名称:变量类型 = 初始值
- 其中
val
定义的是不可重新赋值的变量(值不可修改)var
定义的是可重新赋值的变量(值可以修改)
- ps
- scala中声明变量是变量名称在前,变量类型在后,跟java是正好相反
- 可以自动识别类型
- scala的语句最后不需要添加分号
- scala中声明变量是变量名称在前,变量类型在后,跟java是正好相反
- 2、演示
//使用val声明变量,相当于java中的final修饰,不能在指向其他的数据了
val a:Int = 10
//使用var声明变量,后期可以被修改重新赋值
var b:Int = 20
b=100
//scala中的变量的类型可以显式的声明,也可以不声明,如果不显式的声明这会根据变量的值来推断出来变量的类型(scala支持类型推断)
val c = 20
- 3、惰性变量
- Scala中使用==关键字lazy==来定义惰性变量,实现延迟加载(懒加载)。
- 惰性变量只能是==不可变变量==,并且只有在调用惰性变量时,才会去实例化这个变量。
- 语法格式
- Scala中使用==关键字lazy==来定义惰性变量,实现延迟加载(懒加载)。
lazy val 变量名 = 表达式
6. scala中数据类型
- scala中的类型绝大多数和Java一样
数据类型
| 基础类型 | 类型说明 | | —- | —- | | Byte | 8位带符号整数 | | Short | 16位带符号整数 | | Int | 32位带符号整数 | | Long | 64位带符号整数 | | Char | 16位无符号Unicode字符 | | String | Char类型的序列(字符串) | | Float | 32位单精度浮点数 | | Double | 64位双精度浮点数 | | Boolean | true或false |==注意下 scala类型与Java的区别==
- scala中所有的类型都使用大写字母开头
2. 整形使用Int而不是Integer
3. scala中定义变量可以不写类型,让scala编译器自动推断
- scala类型层次结构
类型 | 说明 |
---|---|
Any | 所有类型的父类,,它有两个子类AnyRef与AnyVal |
AnyVal | 所有数值类型的父类 |
AnyRef | 所有对象类型(引用类型)的父类 |
Unit | 表示空,Unit是AnyVal的子类,它只有一个的实例(),它类似于Java中的void,但scala要比Java更加面向对象 |
Null | Null是AnyRef的子类,也就是说它是所有引用类型的子类。它的实例是null, 可以将null赋值给任何对象类型 |
Nothing | 所有类型的子类不能直接创建该类型实例,某个方法抛出异常时,返回的就是Nothing类型,因为Nothing是所有类的子类,那么它可以赋值为任何类型 |
7. scala中的条件表达式
- 条件表达式就是if表达式,if表达式可以根据给定的条件是否满足,根据条件的结果(真或假)决定执行对应的操作。scala条件表达式的语法和Java一样。
//定义变量x
scala> val x =1
x: Int = 1
//if表达式
scala> val y =if(x>0) 1 else -1
y: Int = 1
//支持混合类型表达式
scala> val z = if(x>1) 1 else “error”
z: Any = error
//缺失else 相当于 if(x>2) 1 else ()
scala> val m=if(x>2) 1
m: AnyVal = ()
//scala中有个Unit类,用作不返回任何结果的方法的结果类型,相当于Java中的void,Unit只有一个实例值,写成()
scala> val n=if(x>2) 1 else ()
n: AnyVal = ()
//if(xx) else if(xx) val
scala> val k=if(x<0) -1 else if (x==0) 0 else 1
k: Int = 1
8.scala方法的重载
+-*/%可以完成和Java中相同的工作,但是有一点区别,他们都是方法。你几乎可以用任何符号来为方法命名。
举例:
scala> 1 + 2
等同于:
scala> 1.+(2)
9. scala中的块表达式
- 定义变量时用 {} 包含一系列表达式,其中块的最后一个表达式的值就是块的值。
val x=0
val result={
val y=x+10
val z=y+”-hello”
val m=z+”-kaikeba”
“over”
}
//result的值就是块表达式的结果
//后期一个方法的返回值不需要加上return,把要返回的结果放在方法的最后一行就可以了
在scala解释器中先输入 ==:paste== ,然后写多行代码, 之后按==ctrl+d==结束输入
10. 循环
在scala中,可以使用for和while,但一般推荐使用for表达式,因为for表达式语法更简洁
1 for循环
1、语法结构
for (i <- 表达式/数组/集合 if i条件){
//表达式
}
- 2、演示
- 简单的for循环
- 简单的for循环
//简单的for循环
scala> val nums= 1 to 10
nums: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for(i <- nums) println(i)
1
2
3
4
5
6
7
8
9
10
- 双重for循环
//双重for循环
scala> for(i <- 1 to 3; j <- 1 to 3) println(i10+j)
11
12
13
21
22
23
31
32
33
//双重for循环打印99乘法表
for(i <- 1 to 9; j <- 1 to i){
print(i+”“+j+”=”+ij+”\t”)
if(i==j){
println()
}
}
11=1
21=2 22=4
31=3 32=6 33=9
41=4 42=8 43=12 44=16
51=5 52=10 53=15 54=20 55=25
61=6 62=12 63=18 64=24 65=30 66=36
71=7 72=14 73=21 74=28 75=35 76=42 77=49
81=8 82=16 83=24 84=32 85=40 86=48 87=56 88=64
91=9 92=18 93=27 94=36 95=45 96=54 97=63 98=72 99=81
- 守卫
- 在for表达式中可以添加if判断语句,这个if判断就称为守卫
- 在for表达式中可以添加if判断语句,这个if判断就称为守卫
- if为true,才会执行for语句的块
//语法结构
for(i <- 表达式/数组/集合 if 表达式) {
// 表达式
}
scala> for(i <- 1 to 10 if i >5) println(i)
6
7
8
9
10
- for推导式
- 在for循环体中,可以使用yield表达式构建出一个集合,我们把使用yield的for表达式称之为推导式
- 在for循环体中,可以使用yield表达式构建出一个集合,我们把使用yield的for表达式称之为推导式
// for推导式:for表达式中以yield开始,该for表达式会构建出一个集合
val v = for(i <- 1 to 5) yield i * 10
2 while循环
- scala中while循环和Java中是一致的
- 语法结构
while(返回值为布尔类型的表达式){
//表达式
}
- 演示
scala> var x = 10
x: Int = 10
scala> while(x >5){
println(x)
x -= 1
}
10
9
8
7
6
11. 方法和函数
在scala当中,函数与方法是两个不同的概念,函数是scala当中的一等公民,scala是一门函数式的编程语言,同时兼顾了面向对象语言的特性。
1、方法与函数的定义方式不同
2、方法可以转换成为函数
3、函数就是对象
4、函数可以作为方法的参数
5、函数可以作为方法的返回值
1 方法
- 语法
def methodName (参数名:参数类型, 参数名:参数类型) : [return type] = {
// 方法体:一系列的代码
}
示例一:定义一个最标准的方法,且定义方法的返回值类型为Int类型
def hello(first:String,second:Int) :Int = {
second
}
示例二:定义一个方法,且不定义返回值
注意:如果定义的方法没有返回值,那么方法的返回值会做==自动推断==。根据我们方法的最后一个返回类型来推断我们的方法返回类型
def hello2(first:Int , second:String) ={
//println(first)
//20
}
val hello2Result = hello2(20,”abc”)
println( hello2Result)
示例三:定义一个方法,不定义返回值,可以通过自动推断,返回不同类型的值
def hello3(first:Int,second:String) ={
if(first > 10){
first
}else{
second
}
}
val hello3Result = hello3(5,”helloworld”)
println(hello3Result)
示例四:定义一个方法,参数给定==默认值==,如果不传入参数,就使用默认值来代替
def hello4(first:Int = 10,second:String)={
println(first+”\t”+ second)
}
//注意我们在调用方法的时候我们可以通过参数名来指定我们的参数的值
hello4(second=”helloworld”)
示例五:变长参数,方法的参数个数不定的,类似于java当中的方法的…可变参数
def hello5(first:Int*)={
var result = 0;
for(arg <- first){
result += arg
}
println(result)
}
hello5(10,20,30)
hello5(10,50)
如果方法除了变长参数外,还有其他参数,那么变长参数必须在参数列表的最后,否则报错
def hello7(first: String, second: Int) = {
var result = 0;
for (arg <- second) {
result += arg
}
println(s”$first $result”)
}
hello7(“最后的和:”, 1, 3, 5)
示例六:递归函数。我们可以定义一个方法,使得方法自己调用自己,形成一个递归函数,但是方法的==返回值类型必须显示的手动指定==
def hello6(first:Int):Int={
if(first <= 1){
1
}else{
first hello6(first -1)
}
}
val hello6Result = hello6(10)
println(hello6Result)
示例七:定义一个方法,没有显示的指定返回值,那么我们方法当中定义的等号可以省掉
注意:如果省掉了=号,那么这个方法强调的就是一个代码执行的过程
/*
定义了一个方法,但是方法的返回值没有显示指定,
此时我们就可以省掉方法定义的=号,如果省掉 = 号,
那么这个方法强调的是一个过程,代码执行的过程,
不会产生任何的返回值
@param first
*/
def hello7(first:Int){
println(first)
30
}
println(hello7(20))
示例八:直接通过def定义一个方法
def hello8=10
val hello8Result = hello8
println(hello8Result)
示例九:如果方法体当中只有一行代码,我们也可以省掉大括号
def hello10(first:Int,second:Int) = first+second
val hello10Result = hello10(10,20)
println(hello10Result)
2 函数
函数定义的两种形式
第一种形式:
val 函数名 = (参数名1:参数类型1,参数名2:参数类型2) => {函数体}
第二种形式:
val 函数名:(参数类型1,参数类型2) => (返回类型) = {
函数体
}
示例一:定义一个标准函数,使用 =>来进行定义
val func1 =(x:Int,y:Int) =>{
x+y
}
func1(2,8)
示例二:定义匿名函数。也就是我们可以定义一个没有名字的函数
定义一个匿名函数之后,这个函数就没法使用了
(x:Int,y:String) =>{x + y}
示例三:函数定义的另外一种形式,定义一个函数,参数只有一个且是Int类型,返回值也是Int类型
val func3 :Int => Int = {x => x * x }
val func3Result = func3(10)
示例四:定义一个函数,参数值是两个,分别是Int和String,返回值是一个元组,分别是String和Int
val func4:(Int,String) =>(String,Int) ={
(x,y) => (y,x)
}
val func4Result = func4(10,”hello”)
println(func4Result)
3 方法和函数的区别
- 方法是隶属于类或者对象的,在运行时,它是加载到JVM的方法区中
- 可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中
==函数是一个对象,继承自FunctionN==,函数对象有apply,curried,toString,tupled这些方法,而方法则没有
4 方法转换为函数
有时候需要将方法转换为函数,作为变量传递,就需要将方法转换为函数
- 使用
_
即可将方法转换为函数 - 示例
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add _
a: (Int, Int) => Int =
12、scala当中的数据结构
1.数据结构基本介绍
Scala同时支持可变集合和不可变集合,不可变集合从不可变,可以安全的并发访问。
两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
Scala优先采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。
不可变集合继承层次:
2. 数组
// 通过指定长度定义数组
val/var 变量名 = new Array元素类型
// 用元素直接初始化数组
val/var 变量名 = Array(元素1, 元素2, 元素3…)
- 注意
在scala中,数组的泛型使用[]来指定
使用()来获取元素
- 演示
scala> val a=new ArrayInt
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> a(0)
res19: Int = 0
scala> a(0)=10
scala> a
res21: Array[Int] = Array(10, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//////////////////////////////////////////////////////////////////
scala> val b =Array(“hadoop”,”spark”,”hive”)
b: Array[String] = Array(hadoop, spark, hive)
scala> b(0)
res24: String = hadoop
scala> b.length
res25: Int = 3
2 变长数组
- 变长数组指的是数组的长度是可变的,可以往数组中添加、删除元素
- 创建变长数组,需要提前导入ArrayBuffer类
import scala.collection.mutable.ArrayBuffer
- 语法
- 创建空的ArrayBuffer变长数组
- 创建空的ArrayBuffer变长数组
val/var a = ArrayBuffer元素类型
- 创建带有初始元素的ArrayBuffer
val/var a = ArrayBuffer(元素1,元素2,元素3….)
- 演示
//导入ArrayBuffer类型
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
//定义一个长度为0的整型变长数组
scala> val a=ArrayBufferInt
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
//定义一个有初始元素的变长数组
scala> val b = ArrayBuffer(“hadoop”, “storm”, “spark”)
b: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, storm, spark)
- 变长数组的增删改操作
- 使用
+=
添加元素 - 使用
-=
删除元素 - 使用
++=
追加一个数组到变长数组
- 使用
- 示例
// 定义变长数组
scala> val a = ArrayBuffer(“hadoop”, “spark”, “flink”)
a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, spark, flink)
// 追加一个元素
scala> a += “flume”
res10: a.type = ArrayBuffer(hadoop, spark, flink, flume)
// 删除一个元素
scala> a -= “hadoop”
res11: a.type = ArrayBuffer(spark, flink, flume)
a += “oozie” -= “spark” //返回ArrayBuffer.this.type类型
// 追加一个数组
scala> a ++= Array(“hive”, “sqoop”)
res12: a.type = ArrayBuffer(spark, flink, flume, hive, sqoop)
//任意位置插入、删除元素;不高效,原因?
a.insert(1, “ai”) //在index 1之前插入元素
//插入多个
a.insert(1, “ml”, “graphx”)
//移除一个
a.remove(1)
//移除多个;第二个参数:移除的元素个数
a.remove(2, 2)
//移除最后2个元素;高效
a.trimEnd(2)
println(a.toString)
//技巧:如果要定义一个Array,但元素个数不确定,可以先将元素写入一个ArrayBuffer,然后再将ArrayBuffer转换成Array
a.toArray
//相似的,可以将Array转换成ArrayBuffer
val arr00 = Array(1, 2, 3)
arr00.toBuffer
//scala集合可以与java集合互转
3. 遍历数组
- 可以使用以下两种方式来遍历数组:
- 使用==for表达式== 直接遍历数组中的元素
- 使用 ==索引== 遍历数组中的元素
- 使用==for表达式== 直接遍历数组中的元素
- 示例
scala> for(i <- a)println(i)
hadoop
hive
flume
spark
scala> for(i <- 0 to a.length -1 )println(a(i))
hadoop
hive
flume
spark
scala> for(i <- 0 until a.length) println(a(i))
hadoop
hive
flume
spark
//0 until n ——生成一系列的数字,包含0,不包含n
//0 to n ——包含0,也包含n
for(i <- 0 until (a.length, 2)) println(a(i))
4 数组常用操作
- scala中的数组封装了丰富的计算操作,将来在对数据处理的时候,不需要我们自己再重新实现。
- 求和——sum方法
- 求最大值——max方法
- 求最小值——min方法
- 排序——sorted方法
- 求和——sum方法
- 示例
scala> val array=Array(1,3,4,2,5)
array: Array[Int] = Array(1, 3, 4, 2, 5)
//求和
scala> array.sum
res10: Int = 15
//求最大值
scala> array.max
res11: Int = 5
//求最小值
scala> array.min
res12: Int = 1
//生成新的数组,升序;array保持不变
scala> array.sorted
res13: Array[Int] = Array(1, 2, 3, 4, 5)
//降序 reverse 反转
scala> array.sorted.reverse
res14: Array[Int] = Array(5, 4, 3, 2, 1)
val array01=Array(“Hello”, “Spark”, “Flink”, “Kafka”)
array01.min
array01.max
3. 元组
val/var 元组变量名称 = (元素1, 元素2, 元素3….)
- 使用箭头来定义元素(元组只有两个元素)
2 示例
// 可以直接使用括号来定义一个元组
scala> val a = (1, “张三”, 20, “北京市”)
a: (Int, String, Int, String) = (1,张三,20,北京市)
//使用箭头来定义元素
scala> val b = 1->2
b: (Int, Int) = (1,2)
val c = (1, 2)
3 访问元组
使用
_1、_2、_3….
来访问元组中的元素,_1表示访问第一个元素,依次类推
- 示例
scala> val a = (1, “张三”, 20, “北京市”)
a: (Int, String, Int, String) = (1,张三,20,北京市)
//获取元组中的第一个元素
scala> a._1
res18: Int = 1
//获取元组中的第二个元素
scala> a._2
res19: String = 张三
//获取元组中的第三个元素
scala> a._3
res20: Int = 20
//获取元组中的第四个元素
scala> a._4
res21: String = 北京市
//不能修改元组中的值
scala> a._4=”上海”
a._4=”上海”
^
4. 映射Map
val/var map = Map(键->值, 键->值, 键->值…) // 推荐,可读性更好
val/var map = Map((键, 值), (键, 值), (键, 值), (键, 值)…)
- 演示
scala> val map1 = Map(“zhangsan”->30, “lisi”->40)
map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 40)
scala> val map2 = Map((“zhangsan”, 30), (“lisi”, 30))
map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 30)
// 根据key获取value
scala> map1(“zhangsan”)
res10: Int = 30
map1(“zhangsan”) = 20 //报错
2 可变Map
- 可变Map需要手动导入==import scala.collection.mutable.Map==, 定义语法与不可变Map一致。
- 演示
//导包
scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map
//定义可变的map
scala> val map3 = Map(“zhangsan”->30, “lisi”->40)
map3: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)
//获取zhangsan这个key对应的value
scala> map3(“zhangsan”)
res26: Int = 30
//给zhangsan这个key重新赋值value
scala> map3(“zhangsan”)=50
//显示map3
scala> map3
res28: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 50)
3 Map基本操作
- 创建一个可变的map
//导包
scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map
scala> val map = Map(“zhangsan”->30, “lisi”->40)
map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)
- 按照key获取value
// 获取zhagnsan的年龄
scala> map(“zhangsan”)
res10: Int = 30
map(“wangwu”) //不存在,报错
// 获取wangwu的年龄,如果wangwu不存在,则返回-1 比较友好,避免遇到不存在的key而报错
scala> map.getOrElse(“wangwu”, -1)
res11: Int = -1
- 修改key对应的value
scala> map(“lisi”)=50
- 添加key-value键值对
scala> map += (“wangwu” ->35)
res12: map.type = Map(lisi -> 50, zhangsan -> 30, wangwu -> 35)
//添加、更新多个键值对
map += (“wangwu” ->25, “lisi” -> 10)
//等价
map(“wangwu”) = 35
- 删除key-value键值对
scala> map -=”wangwu”
res13: map.type = Map(lisi -> 50, zhangsan -> 30)
- 获取所有的key和所有的value
//获取所有的key
scala> map.keys
res36: Iterable[String] = Set(lisi, zhangsan)
//获取所有的key
scala> map.keySet
res37: scala.collection.Set[String] = Set(lisi, zhangsan)
//获取所有的value
scala> map.values
res38: Iterable[Int] = HashMap(50, 30)
- 遍历map
//第一种遍历
scala> for(k <- map.keys) println(k+” -> “ +map(k))
lisi -> 50
zhangsan -> 30
//第二种遍历
scala> for((k,v) <- map) println(k+” -> “+v)
lisi -> 50
zhangsan -> 30
5. Set集合
//创建一个空的不可变集
val/var 变量名 = Set类型
//给定元素来创建一个不可变集
val/var 变量名 = Set类型
- 演示
// 创建set集合
scala> val a = Set(1,1,2,3,4,5)
a: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
// 获取集合的大小
scala> a.size
res0: Int = 5
// 遍历集合
scala> for(i <- a) println(i)
//添加元素生成新的集合
scala> a + 6
res1: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 3, 4)
// 删除一个元素
scala> a - 1
res2: scala.collection.immutable.Set[Int] = Set(5, 2, 3, 4)
// 删除set集合中存在的元素
scala> a — Set(2,3)
res3: scala.collection.immutable.Set[Int] = Set(5, 1, 4)
// 拼接两个集合
scala> a ++ Set(6,7,8)
res4: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 8, 4)
//求2个Set集合的交集
scala> a & Set(3,4,5,6)
res5: scala.collection.immutable.Set[Int] = Set(5, 3, 4)
//注意:这里对不可变的set集合进行添加删除等操作,对于该集合来说是没有发生任何变化,这里是生成了新的集合,新的集合相比于原来的集合来说发生了变化。
2 可变Set集合
- 要使用可变集,必须要手动导入: ==import scala.collection.mutable.Set==
- 演示
//导包
scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set
//定义可变的set集合
scala> val set=Set(1,2,3,4,5)
set: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4)
//添加单个元素
scala> set +=6 // set = set + 6
res10: set.type = Set(1, 5, 2, 6, 3, 4)
//添加多个元素
scala> set +=(6,7,8,9)
res11: set.type = Set(9, 1, 5, 2, 6, 3, 7, 4, 8)
//添加一个set集合中的元素
scala> set ++=Set(10,11)
res12: set.type = Set(9, 1, 5, 2, 6, 3, 10, 7, 4, 11, 8)
//删除一个元素
scala> set -=11
res13: set.type = Set(9, 1, 5, 2, 6, 3, 10, 7, 4, 8)
//删除多个元素
scala> set -=(9,10)
res15: set.type = Set(1, 5, 2, 6, 3, 7, 4, 8)
//删除一个set子集
scala> set —=Set(7,8)
res19: set.type = Set(1,5, 2, 6, 3, 4)
//将值1从set中删除
scala> set.remove(1)
res17: Boolean = true
scala> set
res18: scala.collection.mutable.Set[Int] = Set(5, 2, 6, 3, 4)
6. 列表 List
- List是scala中最重要的、也是最常用的数据结构。
- List具备以下性质:
- 1、可以保存重复的值
- 2、有先后顺序
- 1、可以保存重复的值
在scala中,也有两种列表,一种是不可变列表、另一种是可变列表
1 不可变列表
不可变列表就是列表的元素、长度都是不可变的
- 语法
- 使用 List(元素1, 元素2, 元素3, …) 来创建一个不可变列表,语法格式
- 使用 List(元素1, 元素2, 元素3, …) 来创建一个不可变列表,语法格式
val/var 变量名 = List(元素1, 元素2, 元素3…)
//使用 Nil 创建一个不可变的空列表
val/var 变量名 = Nil
//使用 :: 方法创建一个不可变列表
val/var 变量名 = 元素1 :: 元素2 :: Nil
- 演示
//创建一个不可变列表,存放以下几个元素(1,2,3,4)
scala> val list1=List(1,2,3,4)
list1: List[Int] = List(1, 2, 3, 4)
//使用Nil创建一个不可变的空列表
scala> val list2=Nil
list2: scala.collection.immutable.Nil.type = List()
//使用 :: 方法创建列表,包含1、2、3三个元素
scala> val list3=1::2::3::Nil
list3: List[Int] = List(1, 2, 3)
2 可变列表
- 可变列表就是列表的元素、长度都是可变的。
- 要使用可变列表,先要导入 ==import scala.collection.mutable.ListBuffer==
- 语法
- 使用ListBuffer元素类型 创建空的可变列表,语法结构
- 使用ListBuffer元素类型 创建空的可变列表,语法结构
val/var 变量名 = ListBufferInt
- 使用ListBuffer(元素1, 元素2, 元素3…)创建可变列表,语法结构
val/var 变量名 = ListBuffer(元素1,元素2,元素3…)
- 演示
//导包
scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer
//定义一个空的可变列表
scala> val a=ListBufferInt
a: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
//定义一个有初始元素的可变列表
scala> val b=ListBuffer(1,2,3,4)
b: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
3 列表操作
//导包
scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer
//定义一个可变的列表
scala> val list=ListBuffer(1,2,3,4)
list: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
//获取第一个元素
scala> list(0)
res4: Int = 1
//获取第一个元素
scala> list.head
res5: Int = 1
//获取除了第一个元素外其他元素组成的列表
scala> list.tail
res6: scala.collection.mutable.ListBuffer[Int] = ListBuffer(2, 3, 4)
//添加单个元素
scala> list +=5
res7: list.type = ListBuffer(1, 2, 3, 4, 5)
//添加一个不可变的列表
scala> list ++=List(6,7)
res8: list.type = ListBuffer(1, 2, 3, 4, 5, 6, 7)
//添加一个可变的列表
scala> list ++=ListBuffer(8,9)
res9: list.type = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
//删除单个元素
scala> list -=9
res10: list.type = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8)
//删除一个不可变的列表存在的元素
scala> list —=List(7,8)
res11: list.type = ListBuffer(1, 2, 3, 4, 5, 6)
//删除一个可变的列表存在的元素
scala> list —=ListBuffer(5,6)
res12: list.type = ListBuffer(1, 2, 3, 4)
//可变的列表转为不可变列表
scala> list.toList
res13: List[Int] = List(1, 2, 3, 4)
//可变的列表转为不可变数组
scala> list.toArray
res14: Array[Int] = Array(1, 2, 3, 4)
13. 函数式编程
课堂问答
先测试一下自己的网络,ok的请call
1
2、完成clickhouse的环境安装
3、判断题:clickhouse中的数据适合高频率、延迟低的修改或删除原有数据
ck它适合做的是olap;题干的假设,是oltp
答案:错误
4、判断题:在clickhouse中,能够创建这样一张表student:包含3列name、age、sid,类型分别是:字符串、数字类型、字符串,表引擎是MergeTree
更正 -》 给的答案正确、错误都给分
MergeTree表
engine=MergeTree(一些参数。。。。)
但是说的是,第一个参数必须是日期
杨俊:
create table student (name String, age UInt8, sid String)
ENGINE=MergeTree() ORDER BY (sid) PRIMARY KEY (sid) SETTINGS index_granularity=8192;
partition by()分区
=====================
spark 版本 源码用的是scala 2.11编写的
scala
解释器
scala语言的任何表达式都是有值的
if
{}
语句 都是有值的 ,都可以复制给一个变量
{} 包含一系列表达式,其中块的最后一个表达式的值就是块的值。
方法和函数 -> 本堂课的重点
1、方法与函数的定义方式不同
2、方法可以转换成为函数
3、函数就是对象
4、函数可以作为方法的参数
5、函数可以作为方法的返回值
scala : 函数式编程 + 面向对象编程
函数是头等公民 -》
Int数字 -》
可以做方法或函数的参数
可以做方法或函数的返回值
可以赋值给其他的变量
函数 -》
可以做方法或函数的参数
可以做方法或函数的返回值
可以赋值给其他的变量
def hello(first: String, second: Int) = {
second
}
def hello5(second: String, first: Int = 10) = {
println(first + “\t” + second)
}
public void mayFunc(int* x){
}
奔腾的小野马:匿名怎么调用
匿名函数要想调用的话,要么是作为其他方法、函数的参数或返回值
或者就想调用匿名函数本身不的逻辑
val func1 = 函数
func1(参数)
scala> val b = Array(“hadoop”, “spark”, “hive”)
b: Array[String] = Array(hadoop, spark, hive)
Array类 -》 半生对象 Array apply方法 {new ArrayInt}
++=:
+=: