spark学习准备(1)——光速入门scala语法(在熟悉java的基础上)

一、变量

1.在scala中,可以使用val或var定义变量,语法格式如下

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

其中

  1. val定义的是不可重新赋值的变量
  2. var定义的是可以重新赋值的变量

2.通过类型推断来定义变量

scala可以自动根据变量的值来推断变量类型,使代码更简洁

var name = "tom"

3.惰性赋值

当有一些变量保存的数据比较大,但不需要马上加载到JVM中。可以使用惰性赋值,语法格式如下

lazy val/var 变量名 = 表达式

二、字符串

1.scala提供多种定义字符串的方式

  1. 使用双引号
val/var 变量名 = "字符串"
  1. 使用插值表达式,避免大量字符串拼接
//在定义字符串之前添加s
//在字符串中,可以使用${}来引用变量或者表达式
val/var 变量名 = s"${变量/表达式}字符串"

举例
在这里插入图片描述

  1. 使用三引号。三个引号中间的所有字符串都将作为字符串的值
val/var 变量名 = """字符串"""

三、数据类型与操作符

scala中的类型以及操作符绝大数和java一样。我们主要学习与java不同的地方

1.数据类型

在这里插入图片描述
注意

  1. scala 中所有类型都是使用大写字母开头

2.运算符

在这里插入图片描述
注意

  1. scala中没有++和–
  2. 与java不一样,在scala中,可以直接==,!=进行比较,它们 equals方法保持一致。而比较两个对象的引用之,则使用eq

3.数据类型结构体系

在这里插入图片描述
说明

  1. scala所有数据类型都是Any
  2. 基本数据类型是继承AnyVal
  3. 引用类型是继承AnyRef的
  4. Null是所有引用类型的字类
  5. Nothing是所有数据类型的字类,可以赋值给任意类型,当一个方法抛出异常时,将会放回Nothing
  6. Unit表示空,只有一个实例(),类似于java中void

四 条件表达式和循环

1.有返回值的if

与java不一样的是

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

示例

var sex = "male"
val result = if(sex == "male") 1 else 0
println(result)

在这里插入图片描述

2.块表达式

  1. scala中,使用{}表示一个块表达式
  2. 块表达式也是有值的,为最后一个表达式的值
    在这里插入图片描述

3. for表达式

语法

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

示例:使用for打印1到10
我们先获得一个数字集合
在这里插入图片描述
然后在进行循环
在这里插入图片描述
简写方式(中缀调动法)
在这里插入图片描述

3.1 for嵌套循环

示例

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

3.2守卫

for表达式中,可以添加if判断语句
只有符合if表达式,才会执行for中的代码

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

3.3for推导式

可以使用for推导式生成一个新的集合
示例

val v = for(i <- 1 to 10) yield i*10

像不像java8集合的stream操作?

4.while循环

scala中while循环和Java是一致的
示列

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

补充

scala中没有关键字break和continue

如果一定要使用他俩,就需要用scala.util.control包Break类的breable和break方法
在这里插入图片描述
在这里插入图片描述

五、方法

1.定义方法

def 方法名(参数名:参数类型,参数名:参数类型):[返回类型] ={
}

注意

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

2.方法参数

scala中的方法参数非常灵活

2.1默认参数

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

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

2.2 带名参数

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

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

2.3变长参数

方法参数的个数可以是不确定的
语法如下

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

3.方法的调用方式

3.1 后缀调用法

语法

对象名.方法名(参数)

3.2 中缀调用法

语法

对象名 方法名 参数

如果有多个参数,使用{}将参数括起来
补充:
在scala中,操作符即方法

1 + 1

观察一下,操作符的使用方式和中缀调用法是一样的

3.3 花括号调用法

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

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

3.4无括号调用法

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

Hello()
//如果这个方法没有参数,则可以直接写成这样
Hello

六、函数

scala支持函数编程,将来我们会大量使用到函数

1.定义函数

语法

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

说明

  1. 函数是一个对象
  2. 类似于方法,函数也有输入参数和返回值
  3. 函数定义不需要用def定义
  4. 无需指定返回值类型
    示例:定义一个两个数值相加的函数
val addFunc = (x:Int,y:Int)=> x+y
addFunc(1,2)

2.方法和函数的区别

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

3.方法转换为函数

有时候需要将方法转换成函数,作为变量传递
使用_即可将方法转换成函数
示例在这里插入图片描述

七、数组

在scala中,有定长和变长数组

1.定长数组

定长数组的长度不允许改变

val 变量名 = new Array[元素类型](数组长度)

用元素直接初始化数组

val 变量名 = Array(元素1,元素2)

注意

  1. 在scala中,数组的泛型使用[]给定
  2. 使用()来获取元素

2.变长数组

2.1定义变长数组

创建变产数组,需要导入scala.collection.mutable.ArrayBuffer类
语法
创建空的ArrayBuffer

val a = ArrayBuffer[元素类型]()

创建带有元素的ArrayBuffeer

val a = ArrayBuffer(元素1,元素2)

2.2 增删改元素

  1. 使用+=添加元素
  2. 使用-=删除元素
  3. 使用++=追加一个数组到变长数组

3.遍历数组

在scala中有两种方式遍历数组

  1. 使用 for表达式
  2. 使用索引

3.1使用for表达式遍历数组

for (i<-a) pringln(i)

在这里插入图片描述

3.2 使用索引遍历数组

for(i<- 0 to a.length-1) println(a(i))

在这里插入图片描述

4.数组常用算法

scala中的数组封装了一些常用的算法,不需要我们自己实现

4.1求和

a.sum

4.2 最大值

a.max

4.3 最小值

a.min

4.4排序

数组的sorted方法可以对数组进行升序排序,reverse方法可以将数组反装

a.sorted
a.reverse

8.元组

元组可以用来包含一组不同类型的值,元组的元素是不可变

1.定义元组

使用括号

val 元组=(元素1,元素2,元素3

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

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

2.访问元组

使用_1,_2,_3…来依次访问元素的元素
示例
在这里插入图片描述

八、scala中的集合

1.列表

列表是scala中最常用的数据结构
List可以保存重复的值,有先后顺序
在scala中有不可变和可变两种列表

1.1不可变列表

语法

val 变量名 = List(元素1,元素2//创建一个不可变的空表
val 变量名 = Nil
//使用::方法创建一个不可便列表,必须在最后添加一个Nil
val 变量名 = 元素1::元素2::Nil

1.2 可变列表

使用可变列表,需要导入scala.collection.mutable.ListBuffer
可变集合都在mutable包中。
不可变集合都在immutable包中(默认导入)

1.2.1 定义可变列表
val 变量名 = ListBuffer[元素类型](元素1,元素2)
val 变量名 = ListBuffer(元素1,元素2)
1.2.2可变列表操作
  1. 获取元素:使用括号访问
  2. 添加元素:+=
  3. 追加一个列表:++=
  4. 删除:-=
  5. 转换为List:toList
  6. 转成Array:toArray

1.3 列表常用操作

在这里插入图片描述
说明的地方

  1. tail获取的是首个元素之后的所有元素
  2. take方法返回你给出的前n个元素,drop获取take以为的元素
  3. 扁平化flaten是将列表中的所有元素放到一个列表中(消灭所有子表)
  4. 拉链是将两个列表组成一个元素为元组的列表,拉开是将一个包含元组的列表解成包含两个列表的元组

2.Set

Set是代表没有重复元素的集合,不保证插入顺序
可变集合不可变集的创建方式一致,需要导入scala.collection,mutable.set。导入之后,我们创建的就是可变set
语法

val a =Set[类型]()
val a = Set(元素1,元素2)

在这里插入图片描述

3.Map

Map也分为元素可变和不可变
同样,导入scala.collection.mutable.Map之后,我们定义的Map就是可变的

3.1 定义Map

val map = Map(->值,键->)
val map = Map((键,值)(键,值))

4.迭代器

与java集合的迭代器基本上是一样的

  1. 使用集合的iterator方法可以获得迭代器
  2. hasNext方法判断是否有下一个元素
  3. next返回下一个元素

九.函数式编程

将来我们用Spark/Flink编写业务时会大量用到函数式编程。下面这些操作是我们重点要掌握的

  1. 遍历(foreach)
  2. 映射map
  3. 映射扁平化flatmap
  4. 过滤filter
  5. 是否存在exists
  6. 排序sorted,sortBy,sortWith
  7. 分组groupBy
  8. 聚合计算reduce
  9. 折叠fold

和java8的stream差不多
PS,如果参数只在函数体中出现一次,且没有嵌套调用,可以使用_代替参数究极简化

1.foreach

方法前面
foreach(f : (A) => Unit):Unit
说明
在这里插入图片描述
示列
在这里插入图片描述
在这里插入图片描述

2.map

map方法接收一个函数,将这个函数应用到每一个元素,最后返回一个新集合
在这里插入图片描述

3.flatMap

可以把flat理解成先把集合map返回一个新集合,然后再把新集合flatten
示列

在这里插入图片描述
在这里插入图片描述

4.filter

将集合中符合条件的元素筛选出来,返回一个新集合
在这里插入图片描述

5.排序

在scala集合中,可以使用以下三种方式排序

  1. sorted默认升序排序
  2. sortBy指定字段排序
  3. sortWith自定义排序

5.1 sorted

在这里插入图片描述

5.2 sortBy

根据传入的函数转换后,再进行排序
示列
将列表按元素中的单词首字母排序而不是数字
在这里插入图片描述

5.3 sortWith

根据传入的函数直接排序
这个函数接收两个参数
在这里插入图片描述

6.groupBy

groupBy接收一个函数,将集合相同特性的元素归为同一个key,最后返回一个map
在这里插入图片描述

7.聚合

聚合可以将列表中的数据合并成为一个。

7.1 reduce

reduce接收一个函数,用来对元素不断地进行聚合操作
函数的第一个参数类型为:当前聚合后的变量
第二个参数类型为:当前要聚合的元素
reduce的执行流程
在这里插入图片描述
注意

  1. reduce和reduceLeft效果一致,表示从左向右进行聚合
  2. reduceRight表示从右到左计算
    示例
    在这里插入图片描述

7.2 fold

fold和reduce很像,只是要给定一个原始值
fold接收一个函数,第一个参数列表为初始值
第二个参数列表就是reduce那俩
同样fold有foldLeft和foldRight
在这里插入图片描述

十、面向对象

1.创建类和对象

用法

  1. 使用class来定义类
  2. 使用new来创建对象
//object的意思是单例对象,main方法只能存在于单例对象中
object test1 {
  class Person{
  }
  def main(args: Array[String]): Unit = {
    val person = new Person()
  }
}

2.简写方式

如果一个类没有任何成员,则可以省略{}
如果构造器是无参的,则new 对象时可以省略括号

object test1 {
  class Person
  def main(args: Array[String]): Unit = {
    val person = new Person
  }
}

3.成员变量和成员方法

3.1成员变量

用法

  1. 在类中使用var/val来定义成员变量
  2. 对象直接使用成员变量名称来访问成员变量
class Person{
    var name:String = ""
    var age:Int = 0


  }
  def main(args: Array[String]): Unit = {
    val person = new Person
    person.name = "张三"
    person.age = 20
  }

3.2使用下划线来初始化成员变量

在定义var类型成员变量时,可以使用_来初始化成员变量。比如String类型初始化就是null,Int类型就是0
val类型从成员变量,必须要手动初始化

  class Person{
    var name:String = _
    var age:Int = _
  }

3.3 成员方法

使用def来定义成员方法

 class Person{
    var name:String = _
    var age:Int = _
    def setAndgetName(x:String):String =
    {
      this.name = x
      this.name
    }
  }

4.访问修饰符

和java类似,scala中可以在成员前面添加private/protected关键字来控制成员的可见性
在scala没有public关键字,任何没有标注private/protected的成员都是公共的

5.类的主构造器

在scala中

  1. 主构造器的参数列表是直接定义在类名后面,可以通过主构造器直接定义成员变量
  2. 整个class中,除了字段定义和方法定义,都是构造代码
    在这里插入图片描述

6.类的辅助构造器

在scala类中,名为this的方法就类的辅助构造方法
语法

def this(参数名:类型,参数名:类型)
{
//第一行必须要调用主构造器或者其他构造器
}

7 单例对象

scala中没有Java中的static,我们想要实现相同的功能,就需要使用单例对象:object

  1. 单例对象表示全局仅有一个对象
  2. 在objiect中定义的成员变量类似于Java的静态变量
  3. 可以使用object直接引用成员变量

8 伴生对象

在Java类中,可同时拥有实例成员和静态成员
在scala中,要实现类似的效果,可以使用伴生对象

8.1 定义伴生对象

一个class和object具有同样的名字。这个object称为伴生对象,这个class成为伴生类

  1. 伴生对象和伴生类名字必须相同
  2. 伴生对象和伴生类在同一个scala源文件中
  3. 伴生对象可以互相访问伴生类的private属性(但不能访问被private[this]修饰的成员)
class Person(var name:String ="初始值",var age:Int =0){
    println(this.name)
    println(Person.classnumber)

    def setAndgetName(x:String):String =
    {
      this.name = x
      this.name
    }
  }
  object Person
  {
    private val classnumber =123
  }

8.2 apply方法

apply方法可以让我们不使用new就可以创建对象
创建一个类的伴生对象,实现apply方法,当创建类的时候,就可以省略new

object 伴生对象名{
       def apply(参数名:参数类型,参数名:参数类型) = new(...)
}

object test1 {
  class Person(var name:String ="初始值",var age:Int =0){
    println(this.name)
    println(Person.classnumber)

    def setAndgetName(x:String):String =
    {
      this.name = x
      this.name
    }
  }
  object Person
  {
    private val classnumber =123
    def apply(name:String,age:Int)=new Person(name,age)
  }
  def main(args: Array[String]): Unit = {

    val person = Person("张山",18)
    println(person.name)
  }
}

9.继承

scala中和java一样,使用extends实现继承
用法

class/object extends
  1. 字类要覆盖父类中的方法或者val类型的字段(var不行),必须使用override关键字
  2. 使用super引用父类

10. 类型判断

在scala中

  1. isIntanceOf判断对象是否为指定类以及其字类的对象
  2. asInstanceOf将对象转换为指定类型
    用法
  3. getClass可以精确获取对象的类型
  4. classOf[x]可以获取x的类型
  5. 使用==操作复可以直接比较类型
对象.isInstanceOf[类型]
对象.asInstanceOf[类型]

11.抽象类

如果类的某个成员在当前类中的定义是不完整,它就是一个抽象类

  1. 方法没有方法体(抽象方法)
  2. 变量没有初始化(抽象字段)
    定义抽象类和java一样,就是在类前加上abstract

12.匿名内部类

匿名内部类是没有名称的字类,直接用来创建实例对象
用法和java相同
语法

val 变量名 = new{
//重写方法
}

13.特质(trait)

scala没有inferface,替代的概念是trait
定义

  1. 特质是scala种代码复用的基础单元
  2. 它可以将方法和字段定义封装起来,添加到类中
  3. 与类继承不一样的是,一个类可以添加多个特质
  4. 特质的定义和抽象类很像,但它是使用trait关键字
  5. 特质可以定义具体字段和具体方法
trait 名称{
//抽象字段
//抽象方法
//具有方法
}

继承特质也是使用extends

classextends 特质1 with 特质2{
}

对象混入trait

scala中可以将trait混入到对象中,就是将trait中定义的方法、 字段添加到一个类中
语法

val 对象名 = newwith 特质

trait的构造机制

trait也有构造代码,但特质不能有构造器参数
每个特质只有一个无参数的构造器
一个类继承另一个类,以及多个trait,当创建该类的实例时,它的构造顺序如下
1.执行父类构造器
2.从左到右依次执行trait的构造器
3.如果trait有父trait,先构造父trait,如果多个trait有同样的父trait,则只初始化依次
4.执行字类构造器

trait继承class

trait也可以继承class,将class的成员继承下来。。。。。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值