scala 学习笔记(上)| 开发环境安装 | 循环判断 | 数据类型

Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。


在这里插入图片描述


下面是我的scala学习笔记连接:

一、开发环境安装

1、安装JDK

2、安装Scala SDK

安装的版本为Scala 2.11.12

下载地址:https://scala-lang.org/download/2.11.12.html

在这里插入图片描述

一路点击安装,注意安装路径不能有中文与空格!

踩个坑,如果安装之后输出:

在这里插入图片描述

因为默认安装路径在Program Files文件,这里有有个空格,诶,卸载了重新安装一下

安装成功之后,打开CMD,输入scala -version,输出对应的版本号,就算安装成功了,如下图所示:

在这里插入图片描述

3、安装IDEA Scala插件

打开idea,打开设置,找到Plugins,搜索Scala点击安装即可

二、变量

1、基本定义

Java变量定义:

int a = 0;

Scala变量定义:

val/var 变量标识:变量类型 = 初始值

其中:

  • val:定义的是不可重新赋值的变量
  • var:定义的是可以重新赋值的变量

注意:

  • Scala中定义变量类型写在变量名后面
  • Scala的语句最后不需要添加分号

比如,定义一个变量:

val name:String = "wzq"

2、自动推断

Scala可以自动根据变量的值来自动推断变量的类型,这样编写代码更加简介

打开Scala编译器(win+R,输入scala):比如:

scala> var name = "wzq"
name: String = wzq

3、惰性赋值

当有一些变量保存的数据较大时,但是不需要马上加载到JVM内存,可以使用惰性赋值来提高效率

语法格式:

lazy val/var 变量名 = 表达式

三、字符串

scala提供多种定义字符串的方式,将来我们可以根据需要来选择最方便的定义方式,分别是:

  • 使用双引号

    val/var 变量名 = "字符串"
    
  • 使用插值表达式,可以有效避免大量字符串的拼接

    val/var 变量名 = s"${变量/表达式}字符串"
    

    需要注意的是:

    • 在定义字符串之前添加s
    • 在字符串中,可以使用${}来引用变量或者编写表达式
  • 使用三引号,如果有大段的文本需要保存,就可以使用三引号来定义字符串

    val/var 变量名 = """字符串1
    字符串2"""
    

四、数据类型与操作符

1、数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QecVJO7q-1617962575671)(img/微信截图_20210408164610.png)]

Java的区别是:

  • scala中所有的类型都是用大写字母开头
  • 整形使用Int而不是Integer
  • scala中定义变量可以不写类型,让scala编译器自动推断

2、运算符

在这里插入图片描述

  • scala中没有 ++ – 运算符
  • 与Java不一样,在scala中,可以直接使用 ==、 !=进行比较,他们与equals方法表示一致。而比较两个对象的引用值,使用eq

比如:

有一个字符串“abc“,再创建第二个字符串,值为:在第一个字符串后拼接一个空字符串

然后使用比较这两个字符串是否相等、再查看他们的引用值是否相等

var str1 = "abc"
var str2 = str1 + ""
str1 == str2
结果:res0: Boolean = true
str1.eq(str2)
结果:res1: Boolean = false

3、scala类型层次结构

在这里插入图片描述

在这里插入图片描述

五、条件表达式

就是判断,语法和Java一样,主要写一下跟Java不一样的地方:

1、有返回值的IF

  • 在scala中,条件表达式也是有返回值的
  • 在scala中,没有三元表达式,可以使用if表达式替代三元表达式

示例:

定义一个变量sex,再定义一个result变量,如果sex等于"male",result等于1,否则等于0

val sex = "male"
val result = if(sex == "male") 1 else 0
result: Int = 1

2、块表达式

  • scala中,使用{}表示一个块表达式
  • 和if表达式一样,块表达式也是有值的
  • 值就是最后一个表达式的值
val a = {
    | println("1 + 1")
    | 1 + 1
    | }

a = 2

六、循环

在scala中,可以使用for和while,但一般推荐使用for表达式,因为for表达式语法更简介

1、for表达式

语法:

for(i <- 表达式/数组/集合){
    // 表达式
}

1)简单循环

使用for表达式打印1-10的数字:

步骤:

  • 生成1-10的数字,使用to方法
  • 使用for表达式遍历。打印每个数字

代码1:

val nums = 1.to(10)
for(i <- nums) println(i)

代码2:

for(i <- 1 to 10) println(i) 

2)嵌套循环

使用for表达式,打印以下表达符

* * * * *
* * * * *
* * * * *
for(i <- 1 to 3 ; j <- 1 to 5){
    print("* ");
	if(j == 5)
    	println("")
}

3)守卫

for表达式中,可以添加if判断语句,这个if判断就称之为守卫,我们可以使用守卫让for表达式更简洁

语法:

for(i <- 表达式/数组/集合 if 表达式){
    //表达式
}

示例:使用for表达式打印1-10之间能够整除3的数字:

for(i <- 1 to 10 if(i % 3 == 0)) println(i)

4)for推导式

  • 将来可以使用for推导式生成一个新的集合(一组数据)
  • 在for循环体中,可以使用yield表达式构建出一个集合,我们把yield的for表达式称为推导式

示例:生成一个10、20、30…100的集合

// for推导式:for表达式中以yield开始,该for表达式会构建出一个集合
val v = for(i<- 1 to 10) yield i * 10

2、while循环

语法与java保持一致

示例:打印1-10

var i = 1
while(i<=10){
    | println(i)
    | i = i + 1
    | }

3、break和continue

  • 在scala中,类似Java和C++的break/continue关键字被移除了
  • 如果一定要使用break/continue,就需要使用scala.util.control包的Break类的breable和break方法

1)实现break

用法:

  • 导入Breaks包 import scala.util.control.Breaks._
  • 使用breakable将for表达式包起来
  • for表达式中需要退出循环的地方,添加break()方法调用

示例:使用for表达式打印出1-100的数字,如果数字达到50,退出for表达式

import scala.util.control.Breaks._
breakable{
    for(i <- 1 to 100){
        if(i >= 50) break()
        else println(i)
    }
}

2)实现continue

与break类似,但是:

实现break式用breakable{}将整个for表达式包起来, 而实现continue使用breakable{}将for表达式的循环体包起来就可以了

示例:打印1-100的数字,使用for表达式来遍历,如果数字能整除10,不打印

import scala.util.control.Breaks._
for(i <- 1 to 100){
    breakable{
        if(i%10==0) break()
        else println(i)
    }
}

七、方法

一个类可以有自己的方法,scala中的方法和Java方法类似,但scala与Java定义方法的语法是不一样的。

1、定义方法

语法:

def methodName (参数名:参数类型,参数名:参数类型) : [return type] = {
    //方法体
}

Notes:

  • 参数列表的参数类型不能省略
  • 返回值类型可以省略,由scala编译器自动推断
  • 返回值可以不写return,默认就是{}块表达式的值

示例:

1、定义一个方法,实现两个整形数值相加,返回相加后的结果

2、调用该方法

代码:

def add(a:Int,b:Int) = a + b

scala> add(1,2)
res10: Inte = 3

2、返回值类型推断

scala定义方法可以省略返回值,由scala自动推断返回值类型,这样方法定义后更加简介

Attention

定义递归放啊,不能省略返回值类型

示例:定义一个递归方法求阶乘

def fac(a:Int) : Int = {
    if(a <= 1) 1
    else fac(a-1) * a
}

3、方法参数

scala中的方法参数,使用比较灵活,它支持以下几种类型的参数:

  • 默认参数
  • 带名参数
  • 变长参数

1)默认参数

在定义方法时可以给一个参数定义一个默认值

示例:

1、 定义一个计算两个值相加的放啊,这两个值默认为0

2、调用该方法,不传任何参数

def add(x:Int=0,y:Int=0) = x + y
add()
scala> res0: Int = 0

2)带名参数

在调用方法时,可以指定参数的名称来进行调用

示例:

1、定义一个计算两个值相加的放啊,这两个值默认为0

2、调用该方法,只设置第一个参数的值

def add(x:Int=0,y:Int=0) = x+y
add(x=1)

3)变长参数

如果方法的参数是不固定的,可以定义一个方法的参数是变长参数

def 方法名(参数名:参数类型*):返回值类型 = {
    方法体
}

Notes:

在参数类型后面加一个 * 号,表示参数可以是0个或者多个

示例:

1、定义一个计算若干个值相加的方法

2、调用方法,传入以下数据:1,2,3,4,5

def add(num:Int*) = num.sum

scala> add(1,2,3,4,5)
res1: Int = 15

4、方法调用方式

在scala中,有以下几种方法调用方式:

  • 后缀调用法
  • 中缀调用法
  • 花括号调用法
  • 无括号调用法

在后续编写spark、flink程序时,会使用到这些方法调用方式

1)后缀调用法

与Java没有区别:

对象名.方法名(参数)

示例:使用后缀法Math.abs求绝对值

Math.abs(-1)
res0: Int = 1

2)中缀调用法

对象名 方法名 参数

例如:1 to 10

Tip

如果有多个参数,使用括号括起来

示例:使用中缀法Math.abs求绝对值

Math abs -1

操作符即方法,所有的操作符都是方法

比如:1 + 1

在scala中,+ - * / %等这些操作符和Java一样,但在scala中

  • 所有的操作符都是方法
  • 操作符时一个方法名字是符号的方法

3)花括号调用法

Math.abs{
    //表达式1
    //表达式2
}

Atteantion

方法只有一个参数,才能使用花括号调用法

示例:使用花括号调用法Math.abs求绝对值

Math.abs{-10}
res0: Int = 10

4)无括号调用法

如果方法没有参数,可以省略方法名后面的括号

示例:

  • 定义一个无参数的方法,打印hellp
  • 使用无括号调用法调用该方法
def m3() = println("hello")
m3

八、函数

scala支持函数式编程,将来写spark/flink程序中,会大量使用到函数

1、定义函数

val 函数变量名 = (参数名:参数类型,参数名:参数类型....) => 函数体

Tip

  • 函数是一个对象(变量)
  • 类似于方法,函数也有输入参数和返回值
  • 函数定义不需要使用def定义
  • 无需指定返回类型

示例:

1、定义一个两个数值相加的函数

2、调用该函数

val add = (x:Int=0,y:Int=0) => x+y
add(1,2)
res0 : Int = 3

2、方法和函数的区别

  • 方法是隶属于类或者对象的,在运行时,它是加载到JVM的方法区中
  • 可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中
  • 函数是一个对象,继承自FunctionN,函数对象有apply | curried | toString | tupled这些方法,方法则没有

示例:方法无法赋值给变量

def add(x:Int,y:Int):Int = x + y
val a = add
<concole>:12: error: missing argument list for method add
...

3、方法转换为函数

  • 有时候需要将方法转换为函数,作为变量传递,就需要将方法转换为函数
  • 使用 _即可将方法转换为函数

示例:

1、定义一个方法用来进行两个数相加

2、将该方法转换为一个函数,赋值给变量

def add(x:Int,y:Int):Int = x + y
val a = add _

九、数组

scala中数组的概念是和Java类似的,可以用数组来存放一组数据。scala中,有两种数组,一种是定长数组,另一种是变长数组

1、定长数组

  • 定长数组指的是数组的长度是不允许改变的
  • 数组的元素是可以改变的

语法:

// 通过指定长度定义数组
val/var 变量名 = new Array([元素类型](数组长度))

// 用元素直接初始化数组
val/var 变量名 = Array(元素1,元素2,元素3...)

Note

  • 在scala中,数组的泛型使用 [] 来指定
  • 使用()来获取元素

示例一:

1、定义一个长度为100的整形数组

2、设置第一个元素为110

3、打印第一个元素

val a = new Array(Int)(100)
a(0) = 110
println(a(0))

示例二:

1、定义一个包含以下元素的数组

"java","scala","python"

2、获取数组长度

val a = Array("java","scala","python")
a.length

2、变长数组

变长数组指的是数组的长度是可变的,可以往数组中添加、删除元素

1)定义变长数组

创建变长数组,需要提前导入ArrayBuffer类的import scala.collection.mutable.ArrayBuffer

语法:

  • 创建空的ArrayBuffer变长数组,语法结构

    val/var a = ArrayBuffer[元素类型]()
    
  • 创建带有初始元素的ArrayBuffer

    val/var = ArrayBuffer(元素1,元素2,元素3,...)
    

示例一:定义一个长度为0的整形变长数组

val a = ArrayBuffer[Int]()

示例二:定义一个包含以下元素的变长数组

"hadoop","strom","spark"
val a = ArrayBuffer("hadoop","strom","spark")

2)添加/修改/删除元素

  • 使用+=添加元素
  • 使用-=删除元素
  • 使用++=追加一个数组到变长数组

示例:

1、定义一个变长数组,包含以下元素: “hadoop”,“spark”,“flink”

2、往该变长数组添加一个"flume"元素

3、从该变长数组删除"hadoop"元素

4、再将一个数组,该数组包含"hive","sqoop"追加到变长数组中

// 定义个变长数组
val a = ArrayBuffer("hadoop","spark","flink")
// 追加一个元素
a += "flume"
// 删除一个元素
a -= "hadoop"
// 插入数组
val b = ArrayBuffer("hive","sqoop")
a ++= b
// 修改元素
a(0) = "s"

3、遍历数组

可以使用下面两种方法来遍历数组:

  • 使用for表达式直接遍历数组中的元素
  • 使用索引遍历数组中的元素

示例一:

1、定义一个数组,包含1、2、3、4、5

2、使用for表达式直接遍历,并打印数组中的元素

val a = Array(1,2,3,4,5)
for(i<-a) println(i)

示例二:

1、定义一个数组,包含1、2、3、4、5

2、使用for表达式基于索引下标遍历,并打印数组的元素

val a = Array(1,2,3,4,5)
// to包含开始值和结束值
for(i <- 0 to a.length - 1) println(a(i)) 
// until包含开始值不包含结束值
for(i <- 0 until a.length) println(a(i))

4、数组常用算法

scala中的数组封装了一些常用的计算操作,将来在对数据处理的时候,不需要我们自己再重新实现,

以下为常用的几个算法

  • 求和——sum方法
  • 求最大值——max方法
  • 求最小值——min方法
  • 排序——sorted方法
  • 反转——reverse方法
var a = Array(1,2,3,4,5)
a.sum
var a = Array(1,2,3,4,5)
a.max
var a = Array(1,2,3,4,5)
a.min
var a = Array(281,12,124,6,345)
//升序
a.sorted
//降序
a.sorted.reverse

十、元组

元组可以用来包含一组不同类型的值,例如:姓名、年龄、性别、出生年月,元组的元素是不可变

1、定义元组

使用括号来定义元组

val/var 元组 = (元素1,元素2,元素3....)

使用箭头来定义元组(元组只有两个元素

val/var 元组 = 元素1->元素2

示例:

定义一个元组,包含一个学生的以下数据

在这里插入图片描述

val a = (1,"zhangshan",20,"beijing")

示例:

  • 定义一个元组,包含学生的姓名和年龄(zhangsan、20)
  • 分别使用括号、和箭头来定义元组
val a = ("zhangsan",20)
val b = "zhangsan" -> 20

2、访问元组

使用_1 _2 _3 ...来访问元组中的元素,_1表示访问的第一个元素,以此类推

示例:

  • 定义一个元组,包含一个学生的姓名和性别 “zhangsan”,“male”
  • 分别获取该学生的姓名和性别
val a = "zhangsan" -> "male"
//获取第一个元素
a._1

十一、列表

列表是scala中最重要的、也是最常用的数据结构,List具备以下性质:

  • 可以保存重复的值
  • 有先后顺序

在scala中,也有两种列表,一种是不可变列表,另一种是可变列表

1、不可变列表

定义:不可变列表就是列表的元素、长度都是不可变的

使用List来创建

val/var 变量名 = List(元素1,元素2,元素3...)

使用Nil创建一个不可变的列表

val/var 变量名 = Nil

使用::方法创建一个不可变列表

val/var 变量名 = 元素1 :: 元素2 :: Nil

Tip

使用::创建列表,最后必须是Nil

示例一:创建一个不可变列表,存放以下几个元素1,2,3,4

val a = List(1,2,3,4)

示例二:使用Nil创建一个不可变的空列表

val a = Nil

示例三:使用::方法创建列表,包含-2,-1两个元素

val a = -2 :: -1 :: Nil

2、可变列表

可变列表就是列表的元素、长度都是可变的

要是有可变列表,先要导入import scala.collection.mutable.ListBuffer

Note

  • 可变集合都在mutable包中
  • 不可变集合都在immutable包中

1)定义

使用ListBuffer[元素类型]()创建空的可变列表,语法:

val/var 变量名 = ListBuffer[Int]()

使用ListBuffer(元素1,元素2,元素3...)创建可变列表,语法:

val/var 变量名 = ListBuffer(元素1,元素2,元素3...)

示例一:创建空的整形可变列表

val a = ListBuffer[Int]()

示例二:创建一个可变列表,包含1、2、3、4

val a = ListBuffer(1,2,3,4)

2)可变列表操作

  • 获取元素(使用括号访问(索引值))
  • 添加元素 +=
  • 追加一个列表 ++=
  • 更改元素(使用括号获取元素,然后进行赋值)
  • 删除元素(-=)
  • 转换为List(toList)
  • 转换为Array(toArray)
import scala.collection.mutable.ListBuffer
val a = ListBuffer(1,2,3)
a(0)
a+=4
val b = ListBuffer(4,5,6)
a++=b
a-=7
a.toList
a.toArray

3、列表常用操作

以下是列表常用的操作:

  • 判断列表是否为空(isEmpty

  • 拼接两个列表(++

  • 获取列表的首个元素(head)和剩余部分(tail

  • 反转列表(reverse

  • 获取前缀(take)、获取后缀(drop

  • 扁平化(flaten

    扁平化表示将列表中的列表中的所有元素放到一个列表中
    在这里插入图片描述

  • 拉链(zip)和拉开(unzip

    • 拉链:使用zip将两个列表,组合成一个元素为元组的列表
    • 拉开:将一个包含元组的列表,解开成包含两个列表的元组
  • 转换字符串(toString

  • 生成字符串(mkString

    • mkString方法,可以将元素以分隔符拼接起来,弄人没有分隔符
  • 并集(union)—表示对两个列表取并集,不去重!使用distinct可以去重

  • 交集(intersect

  • 差集(diff):获取a在b中不存在的元素

val a = List(1,2,3,4)

// 判断列表是否为空
a.isEmpty
res1: Boolean = false

//---------------------------------------------------------------

//拼接两个列表
val b = List(4,5,6)
a ++ b
res2: List[Int] = List(1,2,3,4,5,6)

//---------------------------------------------------------------

val a = List(1,2,4)
//获取首个元素
a.head
res3: Int = 1
//获取剩余部分
a.tail
res4: List[Int] = List(2,3)

//---------------------------------------------------------------

//反转列表
a.reverse
res5: List[Int] = List(3,2,1)

//---------------------------------------------------------------
//获取列表前缀和后缀
val a = List(1,2,3,4,5)
//获取前三个元素
a.take(3)
res6: List[Int] = List(1,2,3)
//获取后缀——除前三个以外的元素
a.drop(3)
res7: List[Int] = List(4,5)

//---------------------------------------------------------------
//扁平化
val a = List(List(1,2),List(3,4),List(5))
a.flatten
res8: List[Int] = List(1,2,3,4,5)

//---------------------------------------------------------------
val a = List("zhangsan","lisi","wangwu")
val b = List(19,20,21)
//拉链
a.zip(b)
res9: List[(String,Int)] = List((zhangsan,19),(lisi,20),(wangwu,21))
//拉开
res9.unzip()
res10: (List[String],List[Int]) = (List(zhangsan,lisi,wangwu),List(19,20,21))

//---------------------------------------------------------------
//转换字符串
val a = List(1,2,3,4)
println(a.toSting)
输出:List(1,2,3,4)

//---------------------------------------------------------------
//生成字符串
val a = List(1,2,3,4)
a.mkString
res11: String = 1234
a.mkString(":")
res12: String = 1:2:3:4

//---------------------------------------------------------------
//并集
val a = List(1,2,3,4)
val b = List(2,3,4,5)
a.union(b)
res13: List[Int] = List(1,2,3,4,2,3,4,5)
//并集去重
a.union(b).distinct
res14: List[Int] = List(1,2,3,4,5)

//---------------------------------------------------------------
//交集
val a = List(1,2,3,4)
val b = List(3,4,5,6)
a.intersect(b)
res15: List[Int] = List(3,4)

//---------------------------------------------------------------
//差集
val a = List(1,2,3,4)
val b = List(3,4,5,6)
a.diss(b)
res16: List[Int] = List(1,2)

十二、集

Set是代表没有重复元素的集合,Set具有以下性质:

  • 元素不重复
  • 不保证插入顺序

scala中的集分为两种:可变集 与 不可变集

1、不可变集

定义:创建一个空的不可变集,语法格式:

val/var 变量名 = Set[类型]()

给定元素来创建一个不可变集,语法格式:

val/var 变量名 = Set(元素1,元素2,元素3...)

基本操作:

  • 获取集的大小(size
  • 遍历集(和遍历数组一致)
  • 添加一个元素,生成一个Set(+
  • 拼接两个集,生成一个Set(++
  • 拼接集合列表,生成一个Set(++

2、可变集

定义:可变集合不可变集的创建方式一致,只不过需要提前导入一个可变集类

导入:import scala.collection.mutable.Set

示例:

1、定义一个可变集,包含以下元素:1,2,3,4

2、添加元素5到可变集中

3、从可变集中移除元素1

val a = Set(1,2,3,4)
//添加元素
a+=5
//删除元素
a-=1

十三、映射

Map可以称之为映射,它是由键值对组成的集合,在scala中,Map也分为不可变Map和可变Map

1、不可变Map

语法:

val/var map = Map(->,->,->...)		//推荐,可读性好
val/var map = Map((,),(,),(,)...)
val map = Map("zhangsan"->30)

2、可变Map

定义语法和不可变Map一致,但定义可变Map需要手动导入import scala.collection.mutable.Map

val map = Map("zhangsan"->30,"lisi"->40)
map("zhangsan") = 20

十四、iterator迭代器

scala针对每一类集合都提供一个迭代器iterator用来迭代访问集合

使用iterator来遍历:

  • 使用iterator方法可以从集合获取一个迭代器
  • 迭代器的两个基本操作
    • hasNext——查询容器中是否有下一个元素
    • next——返回迭代器的下一个元素,如果没有,抛出NoSuchElementException
  • 每一个迭代器都是有状态的
    • 迭代完后保留在最后一个元素的位置
    • 再次使用则抛出NoSuchElementException
  • 可以使用while或者for来逐个返回元素
val a = List(1,2,3,4)
val ite = a.iterator
while(ite.hasNext){
    println(ite.next)
}
for(i <- ite) println(i)
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值